github code gate: https://github.com/18380438200/NdkUse
First, the effect picture:
The implementation method of java is as follows:
public class JavaFilter { public static final float brightness = 0.2f; //brightness public static final float contrainst = 0.2f; //Contrast, color deepening public static Bitmap getImageBitmap(Bitmap bitmap){ int width = bitmap.getWidth(); int height = bitmap.getHeight(); Bitmap result = Bitmap.createBitmap(width,height, Bitmap.Config.RGB_565); int a,r,g,b; int bab = (int) (255*brightness); float ca = 1.0f + contrainst; //Change the rgb value of all pixels for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int color = bitmap.getPixel(x,y); //Gets the color value a = Color.alpha(color); r = Color.red(color); g = Color.green(color); b = Color.blue(color); //skin whitening int ri = r + bab; int gi = g + bab; int bi = b + bab; //boundary detection r = ri > 255 ? 255 : (ri<0?0:ri); g = gi > 255 ? 255 : (gi<0?0:gi); b = bi > 255 ? 255 : (bi<0?0:bi); //Enlarge contrast, need white more white, black more black //Strengthen above 128 and reduce below 128 ri = r - 128; gi = g - 128; bi = b - 128; ri = (int) (ri * ca); gi = (int) (gi * ca); bi = (int) (bi * ca); ri += 128; gi += 128; bi += 128; //boundary detection r = ri > 255 ? 255 : (ri<0?0:ri); g = gi > 255 ? 255 : (gi<0?0:gi); b = bi > 255 ? 255 : (bi<0?0:bi); result.setPixel(x,y,Color.argb(a,r,g,b)); } } return result; }
Bitmap.createBitmap()
Create Bitmap (Bitmap source, int x, int y, int width, int height): starting from the coordinate point (x,y) specified in the original position map, dig out a piece of wide width and high height from it to create a new Bitmap object.
Create scaled bitmap (bitmap source, int dstwidth, int dstheight, Boolean filter): zooms the source bitmap to a new bitmap object of specified width and height.
•createBitmap(int width, int height, Bitmap.Config Config): create a new bitmap with wide width and high height.
Create Bitmap (Bitmap source, int x, int y, int width, int height, Matrix matrix, Boolean filter): starting from the coordinate point (x,y) specified in the original position map, dig out a piece of wide width and high height to create a new Bitmap object. And transform according to the rules specified by Matrix.
Bitmap.Config.RGB_ Understanding: the inner class of bitmap
public enum Config {
ALPHA_8 (1),
RGB_565 (3),
ARGB_4444 (4),
ARGB_8888 (5),
RGBA_F16 (6),
...
}
Alpha_ Eight is Alpha, which is made up of eight bits
ARGB_4444 is composed of four 4 bits, namely 16 bits,
ARGB_8888 is composed of 4 8 bits, namely 32 bits, the original color
RGB_565 means that R is 5 bits, G is 6 bits, B is 5 bits, totally 16 bits
The higher the number of bits, the richer the stored colors and the clearer the picture
C implementation code
extern "C" JNIEXPORT jintArray JNICALL Java_com_example_apple_ndkconfig_NdkFilter_getNdkBitmap(JNIEnv *env, jobject /* this */, jintArray buffer_, jint width, jint height) { float brightness = 0.2f; //brightness float contrainst = 0.2f; //Contrast, color deepening //All color values of the image are stored in an array jint* source = env->GetIntArrayElements(buffer_,NULL); int a,r,g,b; int bab = (int) (255 * brightness); float ca = 1.0f + contrainst; //Change the rgb value of all pixels int x,y; for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { int color = source[width*y + x]; //Gets the color value a = color >> 24; r = color >> 16 & 0xFF; g = color >> 8 & 0xFF; b = color & 0xFF; //Increase brightness (whitening) int ri = r + bab; int gi = g + bab; int bi = b + bab; //Boundary detection, argb values are in the range of [0-255] r = ri > 255 ? 255 : (ri < 0 ? 0 : ri); g = gi > 255 ? 255 : (gi < 0 ? 0 : gi); b = bi > 255 ? 255 : (bi < 0 ? 0 : bi); //Enlarge contrast, need white more white, black more black //Strengthen above 128 and reduce below 128 ri = r - 128; gi = g - 128; bi = b - 128; ri = (int) (ri * ca); gi = (int) (gi * ca); bi = (int) (bi * ca); ri += 128; gi += 128; bi += 128; //Boundary detection again r = ri > 255 ? 255 : (ri < 0 ? 0 : ri); g = gi > 255 ? 255 : (gi < 0 ? 0 : gi); b = bi > 255 ? 255 : (bi < 0 ? 0 : bi); //result.setPixel(x, y, Color.argb(a, r, g, b)); //argb synthesis of jni source[width * y + x] = a << 24| r << 16 | g << 8 | b; } } //The processing principle is the same as that of java, but the way to get data and objects is different int newSize = width * height; //According to the length of the array, save the source to jintararray and release the resources jintArray result = env->NewIntArray(newSize); env->SetIntArrayRegion(result,0,newSize,source); env->ReleaseIntArrayElements(buffer_, source, 0); return result; }
a = color >> 24; r = color >> 16 & 0xFF; // (color >> 16) & 0xFF g = color >> 8 & 0xFF; b = color & 0xFF;
Here, because the color value is a 32-bit int, argb occupies 8 bits respectively. Take r = color > > 16 & 0xff as an example,
Shift 16 bits to the right to get the high 16 bits, and then & 0xff, that is, the low eight bits of the process and 1 press the bit and still get the original value, so the corresponding r value is obtained
More NDK development features, see my next blog series.