Android 在JNI中使用像素数据创建新位图?

Android 在JNI中使用像素数据创建新位图?,android,c++,c,android-ndk,java-native-interface,Android,C++,C,Android Ndk,Java Native Interface,我有下面的代码在JNI中使用“ARGB_8888”配置创建一个位图(只是一个黑色/灰色图像)。但是当我在Java代码中转储位图的内容时,我只能看到配置,而不能看到位图中的像素数据 JNI代码 // Image Details int imgWidth = 128; int imgHeight = 128; int numPix = imgWidth * imgHeight; // Creaing Bitmap Config Class jclass bmpCfgCls = env->Fi

我有下面的代码在JNI中使用“ARGB_8888”配置创建一个位图(只是一个黑色/灰色图像)。但是当我在Java代码中转储位图的内容时,我只能看到配置,而不能看到位图中的像素数据

JNI代码

// Image Details
int imgWidth = 128;
int imgHeight = 128;
int numPix = imgWidth * imgHeight;

// Creaing Bitmap Config Class
jclass bmpCfgCls = env->FindClass("android/graphics/Bitmap$Config");
jmethodID bmpClsValueOfMid = env->GetStaticMethodID(bmpCfgCls, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
jobject jBmpCfg = env->CallStaticObjectMethod(bmpCfgCls, bmpClsValueOfMid, env->NewStringUTF("ARGB_8888"));

// Creating a Bitmap Class
jclass bmpCls = env->FindClass("android/graphics/Bitmap");
jmethodID createBitmapMid = env->GetStaticMethodID(bmpCls, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
jBmpObj = env->CallStaticObjectMethod(bmpCls, createBitmapMid, imgWidth, imgHeight, jBmpCfg);

// Creating Pixel Data
int triplicateLen = numPix * 4;
char *tripPixData = (char*)malloc(triplicateLen);
for (int lc = 0; lc < triplicateLen; lc++)
{ 
    // Gray / Black Image
    if (0 == (lc%4))
        tripPixData[lc] = 0x7F; // Alpha
    else
        tripPixData[lc] = 0x00; // RGB
}

// Setting Pixels in Bitmap
jByteArr = env->NewByteArray(triplicateLen);
env->SetByteArrayRegion(jByteArr, 0, triplicateLen, (jbyte*)tripPixData);
jmethodID setPixelsMid = env->GetMethodID(bmpCls, "setPixels", "([IIIIIII)V");
env->CallVoidMethod(jBmpObj, setPixelsMid, (jintArray)jByteArr, 0, imgWidth, 0, 0, imgWidth, imgHeight);

free(tripPixData);

// Return BitMap Object
return jBmpObj;
//图像详细信息
int-imgWidth=128;
int imgHeight=128;
int numPix=imgWidth*imgHeight;
//创建位图配置类
jclass bmpCfgCls=env->FindClass(“android/graphics/Bitmap$Config”);
jmethodID bmpClsValueOfMid=env->GetStaticMethodID(bmpCfgCls,“valueOf”,“(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;”;
jobject jBmpCfg=env->CallStaticObjectMethod(bmpCfgCls,bmpClsValueOfMid,env->NewStringUTF(“ARGB_8888”);
//创建位图类
jclass bmpCls=env->FindClass(“安卓/图形/位图”);
jmethodID createBitmapMid=env->GetStaticMethodID(bmpCls,“createBitmap”,“(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;”;
jBmpObj=env->CallStaticObjectMethod(bmpCls、createBitmapMid、imgWidth、imgHeight、jBmpCfg);
//创建像素数据
int-triplicateLen=numPix*4;
char*tripPixData=(char*)malloc(triplicateLen);
for(int-lc=0;lcNewByteArray(三连体);
env->SetByteArrayRegion(jByteArr,0,三连读,(jbyte*)三连读数据);
jmethodID setPixelsMid=env->GetMethodID(bmpCls,“setPixels”,“([iiiii)V”);
env->CallVoidMethod(jBmpObj,setPixelsMid,(jintArray)jByteArr,0,imgWidth,0,0,imgWidth,imgHeight);
免费(tripPixData);
//返回位图对象
返回jBmpObj;
JAVA语言(输出)

//检查配置/映像详细信息
jBmpObj.getWidth()-128
jBmpObj.getHeight()-128
jBmpObj.getRowBytes()-512
jBmpObj.getConfig()-ARGB 8888
//获取像素数据
imgPixs=newint[jBmpObj.getWidth()*jBmpObj.getHeight()];
jBmpObj.getPixels(imgpix,0,jBmpObj.getWidth(),0,0,jBmpObj.getWidth(),jBmpObj.getHeight());
//在IMGPIX上运行循环
imgPixs[]-0(每个像素数据)
我使用相同的概念在Java代码中创建位图,它工作得很好(即使我能够看到图像)。但我希望逻辑在JNI部分,而不是在Java代码中。因此我尝试了上述逻辑,但设置像素数据失败


解决这个问题的任何输入都会非常有用,…

在Java中不能将byte[]强制转换为int[],因此不能在JNI中强制转换它。但是可以将char*强制转换为int*,因此只需使用TripIxData来填充新的JJITARRAY即可。

不能将byte[]强制转换为int[]因此,在Java中,您不能在JNI中强制转换它,但您可以将char*强制转换为int*,因此您可以简单地使用tripPixData来填充新的JJUnitArray

IN Android each pixel represented as 0xFFFFFFFF ie ARGB.
0xFF referes most significamt 8 bits of given data.
From your snippet, where you are getting soure image data? But i have solved this issue
by using following code base.i hope this ll help you.
//创建像素数据

unsigned char* rawData = //your raw data

**Note**: here you have get each r,g & b component as 8 bit data //If it is rgb image,if it             
is monochrome you can use raw data

int triplicateLen = imgheight * imgwidth;
int *tripPixData = (int*) malloc(triplicateLen * sizeof(int));

if(rgb){
       for (int lc = 0; lc < triplicateLen ; lc++){
            tripPixData [lc] = (0xFF << 24) | (r[lc] << 16) | (g[lc] << 8) | b[lc]; 
       }
 }else{
      for (int lc = 0; lc < triplicateLen ; lc++){
            tripPixData [lc] = (0xFF << 24) | (rawData [lc] << 16) | (rawData [lc] << 8) | rawData [lc];    
       }
 }
unsigned char*rawData=//您的原始数据
**注**:这里您将每个r、g和b组件作为8位数据//如果是rgb图像,如果是
是单色的你可以使用原始数据吗
int triplicateLen=imgheight*imgwidth;
int*tripPixData=(int*)malloc(triplicateLen*sizeof(int));
如果(rgb){
for(int-lc=0;lc
unsigned char* rawData = //your raw data

**Note**: here you have get each r,g & b component as 8 bit data //If it is rgb image,if it             
is monochrome you can use raw data

int triplicateLen = imgheight * imgwidth;
int *tripPixData = (int*) malloc(triplicateLen * sizeof(int));

if(rgb){
       for (int lc = 0; lc < triplicateLen ; lc++){
            tripPixData [lc] = (0xFF << 24) | (r[lc] << 16) | (g[lc] << 8) | b[lc]; 
       }
 }else{
      for (int lc = 0; lc < triplicateLen ; lc++){
            tripPixData [lc] = (0xFF << 24) | (rawData [lc] << 16) | (rawData [lc] << 8) | rawData [lc];    
       }
 }
unsigned char*rawData=//您的原始数据
**注**:这里您将每个r、g和b组件作为8位数据//如果是rgb图像,如果是
是单色的你可以使用原始数据吗
int triplicateLen=imgheight*imgwidth;
int*tripPixData=(int*)malloc(triplicateLen*sizeof(int));
如果(rgb){
for(int-lc=0;lc
jclass bitmapConfig = jniEnv->FindClass("android/graphics/Bitmap$Config");
    jfieldID rgba8888FieldID = jniEnv->GetStaticFieldID(bitmapConfig, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
    jobject rgba8888Obj = jniEnv->GetStaticObjectField(bitmapConfig, rgba8888FieldID);

    jclass bitmapClass = jniEnv->FindClass("android/graphics/Bitmap");
    jmethodID createBitmapMethodID = jniEnv->GetStaticMethodID(bitmapClass,"createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    jobject bitmapObj = jniEnv->CallStaticObjectMethod(bitmapClass, createBitmapMethodID, _width, _height, rgba8888Obj);

    jintArray pixels = jniEnv->NewIntArray(_width * _height);
    for (int i = 0; i < _width * _height; i++)
    {
        unsigned char red = bitmap[i*4];
        unsigned char green = bitmap[i*4 + 1];
        unsigned char blue = bitmap[i*4 + 2];
        unsigned char alpha = bitmap[i*4 + 3];
        int currentPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
        jniEnv->SetIntArrayRegion(pixels, i, 1, &currentPixel);
    }

    jmethodID setPixelsMid = jniEnv->GetMethodID(bitmapClass, "setPixels", "([IIIIIII)V");
    jniEnv->CallVoidMethod(bitmapObj, setPixelsMid, pixels, 0, _width, 0, 0, _width, _height);
jclass-bitmappconfig=jniEnv->FindClass(“android/graphics/Bitmap$Config”);
jfieldID rgba8888FieldID=jniEnv->GetStaticFieldID(位图配置,“ARGB_8888”,“Landroid/graphics/Bitmap$Config;”);
jobject rgba8888Obj=jniEnv->GetStaticObjectField(位图配置,rgba8888FieldID);
jclass-bitmapClass=jniEnv->FindClass(“android/graphics/Bitmap”);
jmethodID createBitmapMethodID=jniEnv->GetStaticMethodID(bitmapClass,“createBitmap”,“(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;”;
jobject bitmapObj=jniEnv->CallStaticObjectMethod(bitmapClass,createBitmapMethodID,_width,_height,rgba8888Obj);
jintArray像素=jniEnv->NewIntArray(\u宽度*\u高度);
对于(int i=0;i<\u宽度*\u高度;i++)
{
无符号字符红色=位图[i*4];
无符号字符绿色=位图[i*4+1];
无符号字符蓝色=位图[i*4+2];
无符号字符alpha=位图[i*4+3];
int currentPixel=(alpha CallVoidMethod(位图对象、设置像素、像素、0、_宽度、0、0、_宽度、_高度);
其中位图为无符号字符*

完整工作示例:

jclass bitmapConfig = jniEnv->FindClass("android/graphics/Bitmap$Config");
    jfieldID rgba8888FieldID = jniEnv->GetStaticFieldID(bitmapConfig, "ARGB_8888", "Landroid/graphics/Bitmap$Config;");
    jobject rgba8888Obj = jniEnv->GetStaticObjectField(bitmapConfig, rgba8888FieldID);

    jclass bitmapClass = jniEnv->FindClass("android/graphics/Bitmap");
    jmethodID createBitmapMethodID = jniEnv->GetStaticMethodID(bitmapClass,"createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    jobject bitmapObj = jniEnv->CallStaticObjectMethod(bitmapClass, createBitmapMethodID, _width, _height, rgba8888Obj);

    jintArray pixels = jniEnv->NewIntArray(_width * _height);
    for (int i = 0; i < _width * _height; i++)
    {
        unsigned char red = bitmap[i*4];
        unsigned char green = bitmap[i*4 + 1];
        unsigned char blue = bitmap[i*4 + 2];
        unsigned char alpha = bitmap[i*4 + 3];
        int currentPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
        jniEnv->SetIntArrayRegion(pixels, i, 1, &currentPixel);
    }

    jmethodID setPixelsMid = jniEnv->GetMethodID(bitmapClass, "setPixels", "([IIIIIII)V");
    jniEnv->CallVoidMethod(bitmapObj, setPixelsMid, pixels, 0, _width, 0, 0, _width, _height);
jclass-bitmappconfig=jniEnv->FindClass(“android/graphics/Bitmap$Config”);
jfieldID rgba8888FieldID=jniEnv->GetStaticFieldID(位图配置,“ARGB_8888”,“Landroid/graphics/Bitmap$Config;”);
jobject rgba8888Obj=jniEnv->GetStaticObjectField(位图配置,rgba8888FieldID);
jclass-bitmapClass=jniEnv->FindClass(“android/graphics/Bitmap”);
jmethodID createBitmapMethodID=jniEnv->GetStaticMethodID(bitmapClass,“createBitmap”,“(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;”;
jobject bitmapObj=jniEnv->CallStaticObjectMethod(bitmapClass,createBitmapMethodID,_width,_height,rgba8888Obj);
jintArray像素=jniEnv->NewIntArray(\u宽度*\u高度);
对于(int i=0;i<\u宽度*\u高度;i++)
{
无符号字符红色=位图[i*4];
无符号字符绿色=位图[i*4+1];
无符号字符蓝色=位图[i*4+2];
无符号字符alpha=位图[i*4+3];
int currentPixel=(alpha CallVoidMethod(位图对象、设置像素、像素、0、_宽度、0、0、_宽度、_高度);
其中位图是无符号字符*