Android NDK: From Elementary to Expert Episode 17

来源:互联网 发布:centos 7 net snmp 编辑:程序博客网 时间:2024/06/06 11:32

Let’s discuss the new topic about image blurring.
There are various kinds of methods to implement this kind of algorithm: JNI Pixels, JNI Bitmap, Java and RenderScript.
The demo I study is:
Image Blurring
It divides the picture into serveral parts:

int divsum = (div + 1) >> 1;divsum *= divsum;short *dv = (short *) malloc(256 * divsum * sizeof(short));for (i = 0; i < 256 * divsum; i++) {   dv[i] = (short) (i / divsum);}

Then calculate the value of red, blue and green. The round is in the specified circle which is the center of x, and the radius is i:

rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;yp = -radius * w;for (i = -radius; i <= radius; i++) {    yi = MAX(0, yp) + x;    sir = stack[i + radius];    sir[0] = r[yi];    sir[1] = g[yi];    sir[2] = b[yi];    rbs = r1 - ABS(i);    rsum += r[yi] * rbs;    gsum += g[yi] * rbs;    bsum += b[yi] * rbs;    if (i > 0) {        rinsum += sir[0];        ginsum += sir[1];        binsum += sir[2];    }    else {        routsum += sir[0];        goutsum += sir[1];        boutsum += sir[2];    }    if (i < hm) {        yp += w;    }}

Preserve the alpha channel:

// Preserve alpha channel: ( 0xff000000 & pix[yi] )pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];

This is a simple implementation of image blurring. It is not the gaussian blurring. It just set a radius to determine a drawed circle to be blurred. And the return or the set each pixel with a value.
That is the final code:

for (y = 0; y < h; y++) {    // Preserve alpha channel: ( 0xff000000 & pix[yi] )    pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];    rsum -= routsum;    gsum -= goutsum;    bsum -= boutsum;    stackstart = stackpointer - radius + div;    sir = stack[stackstart % div];    routsum -= sir[0];    goutsum -= sir[1];    boutsum -= sir[2];    if (x == 0) {        vmin[y] = MIN(y + r1, hm) * w;    }    p = x + vmin[y];    sir[0] = r[p];    sir[1] = g[p];    sir[2] = b[p];    rinsum += sir[0];    ginsum += sir[1];    binsum += sir[2];    rsum += rinsum;    gsum += ginsum;    bsum += binsum;    stackpointer = (stackpointer + 1) % div;    sir = stack[stackpointer];    routsum += sir[0];    goutsum += sir[1];    boutsum += sir[2];    rinsum -= sir[0];    ginsum -= sir[1];    binsum -= sir[2];    yi += w;}

This demo shows how to deal with Bitmap.ARGB88 and Bitmap.RGB656 format. It shows that if we use pixel as the bluring element, we can get the fastest speed, and the RenderScript and Java are not good as the JNI. Therefore it is advisable for use to learn NDK when we are facing the problem about picture editing.