#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image.h" #include "stb_image_write.h" #include void doit( const char *filenameIn, const char *filenameOut, stbi_uc r_fg_old, stbi_uc g_fg_old, stbi_uc b_fg_old, stbi_uc r_bg, stbi_uc g_bg, stbi_uc b_bg, stbi_uc r_fg_new, stbi_uc g_fg_new, stbi_uc b_fg_new) { stbi_uc rDiff = abs(r_bg - r_fg_old); stbi_uc gDiff = abs(g_bg - g_fg_old); stbi_uc bDiff = abs(b_bg - b_fg_old); int x, y, n; stbi_uc *img = stbi_load(filenameIn, &x, &y, &n, 0); for (int i = 0; i < x; i++) { for (int j = 0; j < y; j++) { size_t index = (j*x + i) * n; stbi_uc r = img[index + 0]; stbi_uc g = img[index + 1]; stbi_uc b = img[index + 2]; stbi_uc a = img[index + 3]; stbi_uc rAbs = abs(r - r_fg_old); double rNorm = (double)rAbs / rDiff; stbi_uc gAbs = abs(g - g_fg_old); double gNorm = (double)gAbs / gDiff; stbi_uc bAbs = abs(b - b_fg_old); double bNorm = (double)bAbs / bDiff; img[index + 0] = r_fg_new; img[index + 1] = g_fg_new; img[index + 2] = b_fg_new; img[index + 3] = (stbi_uc)(255.0*(1.0 - ((rNorm + gNorm + bNorm) / 3.0))); } } stbi_write_png(filenameOut, x, y, n, img, 0); stbi_image_free(img); } stbi_uc hex(char *c) { stbi_uc c0 = 0, c1 = 0; if (c[0] >= '0' && c[0] <= '9') c0 = c[0] - '0'; else if (c[0] >= 'a' && c[0] <= 'f') c0 = c[0] - 'a' + 10; if (c[1] >= '0' && c[1] <= '9') c1 = c[1] - '0'; else if (c[1] >= 'a' && c[1] <= 'f') c1 = c[1] - 'a' + 10; return c0*16 + c1; } int main(int argc, char **argv) { if (argc != 6) { fprintf(stderr, "Usage: %s filename_old filename_new fgcolor bgcolor fgcolor_new\n", argv[0]); return 1; } // rgb, foreground and background and new foreground stbi_uc r_f = hex(&argv[3][0]); stbi_uc g_f = hex(&argv[3][2]); stbi_uc b_f = hex(&argv[3][4]); stbi_uc r_b = hex(&argv[4][0]); stbi_uc g_b = hex(&argv[4][2]); stbi_uc b_b = hex(&argv[4][4]); stbi_uc r_n = hex(&argv[5][0]); stbi_uc g_n = hex(&argv[5][2]); stbi_uc b_n = hex(&argv[5][4]); doit( argv[1], argv[2], r_f, g_f, b_f, r_b, g_b, b_b, r_n, g_n, b_n); return 0; }