试试这种抖动算法。 https://en.wikipedia.org/wiki/Ordered_dithering ============================================ /* Dither Tresshold for Red Channel */ static const BYTE dither_tresshold_r[64] = { 1, 7, 3, 5, 0, 8, 2, 6, 7, 1, 5, 3, 8, 0, 6, 2, 3, 5, 0, 8, 2, 6, 1, 7, 5, 3, 8, 0, 6, 2, 7, 1, 0, 8, 2, 6, 1, 7, 3, 5, 8, 0, 6, 2, 7, 1, 5, 3, 2, 6, 1, 7, 3, 5, 0, 8, 6, 2, 7, 1, 5, 3, 8, 0 }; /* Dither Tresshold for Green Channel */ static const BYTE dither_tresshold_g[64] = { 1, 3, 2, 2, 3, 1, 2, 2, 2, 2, 0, 4, 2, 2, 4, 0, 3, 1, 2, 2, 1, 3, 2, 2, 2, 2, 4, 0, 2, 2, 0, 4, 1, 3, 2, 2, 3, 1, 2, 2, 2, 2, 0, 4, 2, 2, 4, 0, 3, 1, 2, 2, 1, 3, 2, 2, 2, 2, 4, 0, 2, 2, 0, 4 }; /* Dither Tresshold for Blue Channel */ static const BYTE dither_tresshold_b[64] = { 5, 3, 8, 0, 6, 2, 7, 1, 3, 5, 0, 8, 2, 6, 1, 7, 8, 0, 6, 2, 7, 1, 5, 3, 0, 8, 2, 6, 1, 7, 3, 5, 6, 2, 7, 1, 5, 3, 8, 0, 2, 6, 1, 7, 3, 5, 0, 8, 7, 1, 5, 3, 8, 0, 6, 2, 1, 7, 3, 5, 0, 8, 2, 6 }; /* Get 16bit closest color */ BYTE closest_rb(BYTE c) { return (c >> 3 << 3); /* red & blue */ } BYTE closest_g(BYTE c) { return (c >> 2 << 2); /* green */ } /* RGB565 */ WORD RGB16BIT(BYTE r, BYTE g, BYTE b) { return ((WORD)((r>>3)<<11)|((g>>2)<<5)|(b>>3)); } /* Dithering by individual subpixel */ WORD dither_xy( int x, int y, BYTE r, BYTE g, BYTE b ){ /* Get Tresshold Index */ BYTE tresshold_id = ((y & 7) << 3) + (x & 7); r = closest_rb( MIN(r + dither_tresshold_r[tresshold_id], 0xff) ); g = closest_g( MIN(g + dither_tresshold_g[tresshold_id], 0xff) ); b = closest_rb( MIN(b + dither_tresshold_b[tresshold_id], 0xff) ); return RGB16BIT(r, g, b); } /* Dithering Pixel from 32/24bit RGB * * GetR, GetG, GetB -> Function to get individual color in pixel * */ WORD dither_color_xy(int x, int y, DWORD col) { return dither_xy(x, y, GetR(col), GetG(col), GetB(col)); } /* EXAMPLES */ void ExampleDither1(WORD * dest, DWORD * src, int width, int height){ int x, y; for (y=0; y<height; y++){ for (x=0; x<width; x++){ int pos = y * width + x; dest[pos] = dither_color_xy(x,y,src[pos]); } } } void ExampleDither2(WORD * dest, BYTE * src, int width, int height){ int x, y; for (y=0; y<height; y++){ for (x=0; x<width; x++){ int pos = y * width + x; dest[pos] = dither_xy(x,y,src[pos*3],src[pos*3+1],src[pos*3+2]); } } } |