Tistory View
Android NDK Access memory of Bitmap directly
What should I do? 2019. 8. 5. 18:59To access bitmap(android.graphics.Bitmap) pixels, getPixel/setPixel/setPixels/getPixels of Bitmap can be used. but, this operation is too slow, Android NDK support to access memory of bitmap directly.
By this method can access memory directly, You can use other C graphic library such as gd and so on and This is very fast.
Usage
include file is <android/bitmap.h> and send "-ljnigraphics" to linker to link this library.
Next code shows how to add this library, if you are using CMakeLists.txt, add "-ljnigraphics" inside of target_link_libraries.
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
-ljnigraphics )
All functions in this library returns C-Style value, On success, returns Zero, Otherwise, returns Non-zero value. In <android/bitmap.h>, Success value, Zero, is defined as ANDROID_BITMAP_RESULT_SUCCESS, Failure return values are defined as negative. Other codes in the world use next snippet to check whether success or not.
if( AndroidBitmap_getInfo( env, bmp, &info ) < 0 ) {
// process on faiure
}
But, I recommend use next snippet, Just because this code is easy to understand.
if( ANDROID_BITMAP_RESULT_SUCCESS != AndroidBitmap_getInfo( env, bmp, &info ) ) {
// procces on failure
}
In this bitmap library has only 3 functions, This is sufficient to use Bitmap memory direclty.
Getting Bitmap information of demensions and format.
int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap, AndroidBitmapInfo* info);
typedef struct {
/** The bitmap width in pixels. */
uint32_t width;
/** The bitmap height in pixels. */
uint32_t height;
/** The number of byte per row. */
uint32_t stride;
/** The bitmap pixel format. See {@link AndroidBitmapFormat} */
int32_t format;
/** Unused. */
uint32_t flags; // 0 for now
} AndroidBitmapInfo;
Supported formats
enum AndroidBitmapFormat {
/** No format. */
ANDROID_BITMAP_FORMAT_NONE = 0,
/** Red: 8 bits, Green: 8 bits, Blue: 8 bits, Alpha: 8 bits. **/
ANDROID_BITMAP_FORMAT_RGBA_8888 = 1,
/** Red: 5 bits, Green: 6 bits, Blue: 5 bits. **/
ANDROID_BITMAP_FORMAT_RGB_565 = 4,
/** Deprecated in API level 13.
Because of the poor quality of this configuration,
it is advised to use ARGB_8888 instead. **/
ANDROID_BITMAP_FORMAT_RGBA_4444 = 7,
/** Alpha: 8 bits. */
ANDROID_BITMAP_FORMAT_A_8 = 8,
};
Sometimes, The format value has ANDROID_BITMAP_FORMAT_NONE even if a valid Bitmap, I can't remember this situations....(In this case, Regenerate bitmap by copying in Java )
The function for getting Pixel ptr.
int AndroidBitmap_lockPixels(JNIEnv* env, jobject jbitmap, void** addrPtr);
When done, You must unlock bitmap.
int AndroidBitmap_unlockPixels(JNIEnv* env, jobject jbitmap);
Typical code skeleton as next.
java code
class YourClass {
.
.
.
.
private native boolean func( Bitmap bmp );
}
Jni code
#include <android/bitmap.h>
extern "C" JNIEXPORT jboolean JNICALL
Java_com_package_name_YourClass_func( JNIEnv *env, jobject _this, jobject bmp )
{
assert( bmp );
int rcc;
jboolean rc = JNI_FALSE;
AndroidBitmapInfo info;
uint8_t* pBmp = NULL;
try {
rcc = AndroidBitmap_getInfo( env, bmp, &info );
if( rcc != ANDROID_BITMAP_RESULT_SUCCESS ) {
throw "get Bitmap Info failure";
}
if( info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 ) {
throw "only ARGB888 format support";
}
rcc = AndroidBitmap_lockPixels( env, bmp, (void**)&pBmp );
if( rcc != ANDROID_BITMAP_RESULT_SUCCESS ) {
throw "lockPixels failure";
}
for( int y = 0 ; y < info.height ; y++ ) {
uint8_t* px = pBmp + y * info.stride;
for( int x = 0 ; x < info.width ; x++ ) {
px[0] = uint8_t( ( (float)x / info.width ) * 255.0f ); // R
px[1] = uint8_t( ( (float)y / info.height ) * 255.0f ); // G
px[2] = 0x00; // B
px[3] = 0xff; // A
px += 4;
}
}
rc = JNI_TRUE;
}
catch( const char* e ) {
}
// unlock, if locking is processed
if( pBmp ) {
AndroidBitmap_unlockPixels( env, bmp );
}
return rc;
}
Pixel Bytes Order has RGBA in LITTLE ENDIAN, I didn't test on BIG ENDIAN devices by absence of those.
If you want not to be care ENDIAN, You can use int. pointer[0xABGR].(Not comfirmed)
'Android Develop > image' 카테고리의 다른 글
안드로이드 ImageView의 ScaleType (0) | 2019.12.04 |
---|---|
Android YV12, stride and RGB conversion (0) | 2019.08.06 |
안드로이드 YV12, stride와 RGB 변환 (4) | 2019.08.06 |
Android NDK Bitmap 메모리에 접근하기 (2) | 2019.08.05 |
늘 괴롭히는 이미지의 stride (2) | 2017.10.30 |
- Total
- Today
- Yesterday
- 사용료
- TTS
- 금리
- 컴퓨트셰이더
- 안드로이드
- 재테크
- 컴퓨트쉐이더
- gpgpu
- OpenGLes
- ComputeShader
- 티스토리
- 텍스처
- OpenGL ES
- 애드센스
- 재태크
- 애드핏
- 아끼는 법
- 전기세
- 적금
- 에어컨
- choreographer
- Android
- 공유 컨텍스트
- 에어콘
- 블로그
- 전기요금
- texture
- 예금
- 경제보복
- 전기료
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |