// // Created by YY on 2021/12/2. // #include #include #include #include #include #include #include "watermark.h" #include "charencode.h" #include "ImageProc.h" #include "apptimer.h" //static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; typedef enum { REVERSE, BLACK, WHITE, RED, GREEN, BLUE } color_t; typedef struct { int x; } wm_t; static char font_path[128] = {0}; static int wm_num = 0; static wm_t *wm = NULL; static int pic_width = 0, pic_height = 0; static color_t wm_color; static void PrintTime(apptimer_var_t val) { text_t text; text.x = 10; text.y = 10; memset(text.text, 0, sizeof (text.text)); strcpy(text.text, FormatTime().c_str()); PrepareWatermark(RED, 24, 2, 1, &text); AppTimer_add(PrintTime, D_SEC(1)); } void InitWatermark(const char *font, int width, int height) { LOGI("InitWatermark"); if (font != NULL) { strcpy(font_path, font); } if (wm != NULL) { free(wm); } wm = (wm_t *)malloc(sizeof(wm_t) * 1000000); wm_num = 0; pic_width = width; pic_height = height; AppTimer_add(PrintTime, D_SEC(1)); } void UninitWatermark(void) { LOGI("UninitWatermark"); if (wm != NULL) { free(wm); wm = NULL; } wm_num = 0; AppTimer_delete(PrintTime); } void PrepareWatermark(int color, int font_size, int multiple, int num, const text_t *texts) { // const char school[] = "驾校:中華人民共和國 济源阳光驾校 aA5"; // const char teacher[] = "教练:黎利伯 让我们编译并运行上面的程序,并使用puts() 语句来重写文件"; // const char student[] = "学员:魏昭杰"; // // const char speed[] = "42.6 km/h"; // const char czh[] = "豫U5966学"; // // const char jwd[] = "35.086601 112.651904"; // const char date[] = "2021-10-22 15:45:36"; const int bytes_per_line = font_size / 8; wm_num = 0; wm_color = static_cast(color); //FILE *fp = fopen("/storage/self/primary/ms_unicode.bin", "rb"); //FILE *fp = fopen("/system/ms_unicode.bin", "rb"); FILE *fp = fopen(font_path, "rb"); if (fp != NULL) { int offset = 0; unsigned long unicode; uint8_t zm[64*64/8]; // 最大 for (int m = 0; m < num; ++m) { const char *str = texts[m].text; int screen_x = texts[m].x; int screen_y = texts[m].y; offset = 0; while (str != NULL && offset < strlen(str)) { int skip = enc_utf8_to_unicode_one(reinterpret_cast(str + offset), &unicode); int next_x = 0; if (skip == 0) { // LOGI("水印文字编码错误"); break; } // 打印一个汉字或Asicc fseek(fp, unicode * (font_size * font_size / 8), SEEK_SET); fread(zm, 1, font_size * font_size / 8, fp); // 32 * 32 点阵,每行占4字节 for (int i = 0; i < font_size * bytes_per_line; ++i) { for (int j = 0; j < 8; ++j) { if (zm[i] & (0x80 >> j)) { // 得到点坐标 int x = (i % bytes_per_line) * 8 + j; int y = i / bytes_per_line; // 放大2倍 64 * 64 x *= multiple; y *= multiple; for (int a = 0; a < multiple; ++a) { for (int b = 0; b < multiple; ++b) { if (wm_num < 999999 && screen_y + y + a < pic_height && screen_x + x + b < pic_width) { wm[wm_num].x = ((screen_y + y + a) * pic_width + screen_x + x + b) * 4; wm_num++; } if (x + b > next_x) { next_x = x + b; } } } } } } offset += skip; if (next_x == 0) { screen_x += font_size * multiple / 2; // 空格间距 } else { screen_x += next_x + font_size * multiple / 12; // 字间距 } } } fclose(fp); } } void AddWatermark(uint8_t *mem) { switch (wm_color) { case BLACK: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] = 0; mem[wm[i].x + 1] = 0; mem[wm[i].x + 2] = 0; } break; case WHITE: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] = 0xFF; mem[wm[i].x + 1] = 0xFF; mem[wm[i].x + 2] = 0xFF; } break; case RED: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] = 0xFF; mem[wm[i].x + 1] = 0; mem[wm[i].x + 2] = 0; } break; case GREEN: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] = 0; mem[wm[i].x + 1] = 0xFF; mem[wm[i].x + 2] = 0; } break; case BLUE: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] = 0; mem[wm[i].x + 1] = 0; mem[wm[i].x + 2] = 0xFF; } break; case REVERSE: default: for (int i = 0; i < wm_num; ++i) { mem[wm[i].x] ^= 0xFF; mem[wm[i].x + 1] ^= 0xFF; mem[wm[i].x + 2] ^= 0xFF; } break; } }