Android Floyd-Steinberg-DitheringStucki-dither 抖动处理
Posted 匆忙拥挤repeat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Floyd-Steinberg-DitheringStucki-dither 抖动处理相关的知识,希望对你有一定的参考价值。
文章目录
I. Floyd-Steinberg-Dithering
Github: Native-Floyd-Steinberg-Dithering
该作者对Floyd-Steinberg-Dithering 的处理中,使用的是静态数组,容易栈溢出。
这里,给出两种实现来避免。当然,若一次处理的位图信息过大,也是会堆溢出,OOM的。
I.i. 动态数组实现
cpp 代码如下。
void floydSteinberg1(androidBitmapInfo *info, void *pixels)
uint32_t *pixelLine;
void *p = pixels;
int w = info->width;
int h = info->height;
// uint32_t ary[h][w];
uint32_t **ary = new uint32_t *[h];
for (int y = 0; y < h; ++y)
ary[y] = new uint32_t[w];
pixelLine = (uint32_t *) p;
for (int x = 0; x < w; ++x)
//extract the RGB values from the pixel
ary[y][x] = 0xFF000000 | (pixelLine[x] & 0x00FFFFFF);
p = (char *) p + info->stride;
for (int y = 0; y < h; ++y)
pixelLine = (uint32_t *) pixels;
for (int x = 0; x < w; ++x)
uint32_t oldPixel = ary[y][x];
// uint32_t newPixel = find_closest_palette_color(oldPixel);
uint32_t newPixel = (int) oldPixel >= 128 ? 0xFFFFFFFF : 0xFF000000;
pixelLine[x] = newPixel;
uint32_t err = oldPixel - newPixel;
if (x + 1 < w)
ary[y][x + 1] += (int) (err * (7. / 16));
if (x > 0 && y + 1 < h)
ary[y + 1][x - 1] += (int) (err * (3. / 16));
if (y + 1 < h)
ary[y + 1][x] += (int) (err * (5. / 16));
if (x + 1 < w && y + 1 < h)
ary[y + 1][x + 1] += (int) (err * (1. / 16));
pixels = (char *) pixels + info->stride;
for (int y = 0; y < h; ++y)
delete ary[y];
delete[] ary;
I.ii. 指针实现
void floydSteinberg2(AndroidBitmapInfo *info, void *pixels)
int w = info->width;
int h = info->height;
int mid = 128;
uint32_t min = 0xFF000000;
uint32_t max = 0xFFFFFFFF;
// uint32_t minWhite = 0xFFFF0000;
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x)
uint32_t pixel = *((uint32_t *) pixels + y * w + x);
// if (pixel >= minWhite && pixel <= max) //接近白色不处理
// continue;
//
uint32_t err = (int) pixel >= mid ? pixel - max : pixel - min;
if (x + 1 < w)
*((uint32_t *) pixels + y * w + (x + 1)) += (int) (err * (7. / 16));
if (x >= 1 && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x - 1)) += (int) (err * (3. / 16));
if (y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + x) += (int) (err * (5. / 16));
if (x + 1 < w && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x + 1)) += (int) (err * (1. / 16));
pixel = (int) pixel >= mid ? max : min;
*((uint32_t *) pixels + y * w + x) = pixel;
II. Stucki
本算法,是从一段c#代码中移植出来的。
void stucki(AndroidBitmapInfo *info, void *pixels)
int w = info->width;
int h = info->height;
int mid = 128;
uint32_t max = 0xFF000000;
uint32_t min = 0xFFFFFFFF;
for (int y = 0; y < h; ++y)
for (int x = 0; x < w; ++x)
uint32_t pixel = *((uint32_t *) pixels + y * w + x);
uint32_t err = (int) pixel >= mid ? pixel - min : pixel - max;
if (x + 1 < w)
*((uint32_t *) pixels + y * w + (x + 1)) += (int) (err * (8. / 42));
if (x + 2 < w)
*((uint32_t *) pixels + y * w + (x + 2)) += (int) (err * (4. / 42));
if (x >= 2 && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x - 2)) += (int) (err * (2. / 42));
if (x >= 1 && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x - 1)) += (int) (err * (4. / 42));
if (y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x)) += (int) (err * (8. / 42));
if (x + 1 < w && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x + 1)) += (int) (err * (4. / 42));
if (x + 2 < w && y + 1 < h)
*((uint32_t *) pixels + (y + 1) * w + (x + 2)) += (int) (err * (2. / 42));
if (x >= 2 && y + 2 < h)
*((uint32_t *) pixels + (y + 2) * w + (x - 2)) += (int) (err * (1. / 42));
if (x >= 1 && y + 2 < h)
*((uint32_t *) pixels + (y + 2) * w + (x - 1)) += (int) (err * (2. / 42));
if (y + 2 < h)
*((uint32_t *) pixels + (y + 2) * w + (x)) += (int) (err * (4. / 42));
if (x + 1 < w && y + 2 < h)
*((uint32_t *) pixels + (y + 2) * w + (x + 1)) += (int) (err * (2. / 42));
if (x + 2 < w && y + 2 < h)
*((uint32_t *) pixels + (y + 2) * w + (x + 2)) += (int) (err * (1. / 42));
pixel = (int) pixel >= mid ? min : max;
*((uint32_t *) pixels + y * w + x) = pixel;
III. 示例
以上是关于Android Floyd-Steinberg-DitheringStucki-dither 抖动处理的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )
Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )