[Android] accesses and operates bitmap elements via JNI, supporting RGB565 and ARGB8888Tags: androidbitmapjni2014-05-09 20:35 2985 People read Comments (1) favorite reports
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
A simple JNI example, the input is bitmap (need to be mutable), the result is to turn bitmap into a grayscale image.
In order to look a bit of value, so at the same time support RGB565 and ARGB8888 (囧RZ)
[CPP]View Plaincopy
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- #include <jni.h>
- #include <android/bitmap.h>
- #include <android/log.h>
- #ifndef eprintf
- #define EPRINTF (...) __android_log_print (Android_log_error, "@", __va_args__)
- #endif
- #define RGB565_R (P) ((((p) & 0xf800) >> one) << 3)
- #define RGB565_G (P) ((((p) & 0X7E0) >> 5) << 2)
- #define RGB565_B (P) (((p) & 0x1F) << 3)
- #define MAKE_RGB565 (R,g,b) (((R) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
- #define RGBA_A (P) (((p) & 0xff000000) >> 24)
- #define RGBA_R (P) (((p) & 0x00ff0000) >> 16)
- #define RGBA_G (P) (((p) & 0x0000FF00) >> 8)
- #define RGBA_B (P) ((p) & 0X000000FF)
- #define MAKE_RGBA (R,g,b,a) (((a) << 24) | (r) << 16) | ((g) << 8) | (b))
- Jniexport void Jnicall java_com_yxcorp_hello_effect_update
- (JNIEnv *env, Jclass clazz, Jobject zbitmap) {
- JNIEnv J = *env;
- if (Zbitmap = = NULL) {
- eprintf ("bitmap is null\n");
- return;
- }
- //Get bitmap Info
- Androidbitmapinfo info;
- memset (&info, 0, sizeof (info));
- Androidbitmap_getinfo (env, Zbitmap, &info);
- //Check format, only RGB565 & RGBA is supported
- if (info.width <= 0 | | info.height <= 0 | |
- (Info.format! = android_bitmap_format_rgb_565 && Info.format! = android_bitmap_format_rgba_8888)) {
- eprintf ("Invalid bitmap\n");
- J->thrownew (env, J->findclass (env, "Java/io/ioexception"), "Invalid Bitmap");
- return;
- }
- //Lock the bitmap to get the buffer
- void * pixels = NULL;
- int res = androidbitmap_lockpixels (env, Zbitmap, &pixels);
- if (pixels = = NULL) {
- eprintf ("fail to lock Bitmap:%d\n", res);
- J->thrownew (env, J->findclass (env, "Java/io/ioexception"), "fail to open bitmap");
- return;
- }
- eprintf ("Effect:%dx%d,%d\n", Info.width, Info.height, Info.format);
- int x = 0, y = 0;
- //From top to bottom
- For (y = 0; y < info.height; ++y) {
- // from left to right
- For (x = 0; x < info.width; ++x) {
- int a = 0, r = 0, g = 0, b = 0;
- void *pixel = NULL;
- //Get each pixel by format
- if (Info.format = = android_bitmap_format_rgb_565) {
- Pixel = ((uint16_t *) pixels) + y * info.width + x;
- uint16_t v = * (uint16_t *) pixel;
- R = Rgb565_r (v);
- g = Rgb565_g (v);
- b = Rgb565_b (v);
- } else {//RGBA
- Pixel = ((uint32_t *) pixels) + y * info.width + x;
- uint32_t v = * (uint32_t *) pixel;
- A = Rgba_a (v);
- R = Rgba_r (v);
- g = Rgba_g (v);
- b = Rgba_b (v);
- }
- //Grayscale
- int Gray = (R * + G * + + b *) >> 7;
- //Write the pixel back
- if (Info.format = = android_bitmap_format_rgb_565) {
- * ((uint16_t *) pixel) = make_rgb565 (Gray, Gray, gray);
- } else {//RGBA
- * ((uint32_t *) pixel) = Make_rgba (Gray, Gray, Gray, a);
- }
- }
- }
- Androidbitmap_unlockpixels (env, ZBITMAP);
- }
[Android] accesses and operates bitmap elements via JNI, supporting RGB565 and ARGB8888