2013-08-27 6 views
5

Android開発用のJNIを使​​用して、AndroidからC++へのビットマップを渡したいと思います。 JavaではAndroid開発環境でJNIを使​​用してJavaからC++にビットマップを渡すにはどうすればよいですか?

、私はJavaからC++へのビットマップを送信するには、この関数を呼び出す:JNIで

public native int sendMyBitmap(Bitmap bitmap); 

、私はこのようにそれを行っている:

JNIEXPORT void JNICALL sendMyBitmap(JNIEnv * env, 
     jobject obj, jobject bitmap) 
{ 
    AndroidBitmapInfo androidBitmapInfo ; 
    void* pixels; 
    AndroidBitmap_getInfo(env, bitmap, &androidBitmapInfo); 
    AndroidBitmap_lockPixels(env, bitmap, &pixels); 
    unsigned char* pixelsChar = (unsigned char*) pixels; 
    saveImage(pixelsChar); 
} 

void saveImage(unsigned char* img) 
{ 
    FILE *f; 
    int w = 640, h = 480; 

    int filesize = 54 + 3*w*h; //w is your image width, h is image height, both int 

    unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; 
    unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; 
    unsigned char bmppad[3] = {0,0,0}; 

    bmpfileheader[ 2] = (unsigned char)(filesize ); 
    bmpfileheader[ 3] = (unsigned char)(filesize>> 8); 
    bmpfileheader[ 4] = (unsigned char)(filesize>>16); 
    bmpfileheader[ 5] = (unsigned char)(filesize>>24); 

    bmpinfoheader[ 4] = (unsigned char)(  w ); 
    bmpinfoheader[ 5] = (unsigned char)(  w>> 8); 
    bmpinfoheader[ 6] = (unsigned char)(  w>>16); 
    bmpinfoheader[ 7] = (unsigned char)(  w>>24); 
    bmpinfoheader[ 8] = (unsigned char)(  h ); 
    bmpinfoheader[ 9] = (unsigned char)(  h>> 8); 
    bmpinfoheader[10] = (unsigned char)(  h>>16); 
    bmpinfoheader[11] = (unsigned char)(  h>>24); 

    f = fopen("/storage/test.png","wb"); 
    fwrite(bmpfileheader,1,14,f); 
    fwrite(bmpinfoheader,1,40,f); 
    for(int i=0; i<h; i++) 
    { 
     fwrite(img+(w*(h-i-1)*3),3,w,f); 
     fwrite(bmppad,1,(4-(w*3)%4)%4,f); 
    } 
    fflush(f); 
    fclose(f); 
} 

をCでビットマップを保存した後++ JNIでは、JavaとC++のビットマップが異なります。私は問題が何かを見つけ出すのに苦労していますし、どうすれば問題を見つけることができますか?

+0

期待される結果と実際の結果をご記入ください – krsteeve

答えて

3

この行:

fwrite(img + (w * (h - i - 1)*3), 3, w, f); 

あなたは入力ビットマップはピクセル当たり24刺さ(3バイト)を有していると仮定されています。しかし、アンドロイドにはそのようなピクセル形式はありません。

また、幅は正確に640ピクセル、高さは正確に480ピクセルと仮定しています。あなたの場合はこれが真実かもしれませんが、値をハードコードするのではなく、この情報を読むべきです。

これらの値はすべて、関数AndroidBitmap_getInfo()によって提供されます。なぜあなたはそれらを使用していないのですか?構造体を確認するだけですAndroidBitmapInfo

typedef struct { 
    uint32_t width; 
    uint32_t height; 
    uint32_t stride; 
    int32_t  format; 
    uint32_t flags;  // 0 for now 
} AndroidBitmapInfo; 

ビットマップの寸法を直接読み取ることができます。

enum AndroidBitmapFormat { 
    ANDROID_BITMAP_FORMAT_NONE  = 0, 
    ANDROID_BITMAP_FORMAT_RGBA_8888 = 1, 
    ANDROID_BITMAP_FORMAT_RGB_565 = 4, 
    ANDROID_BITMAP_FORMAT_RGBA_4444 = 7, 
    ANDROID_BITMAP_FORMAT_A_8  = 8, 
}; 

あなたが参照してください。また、あなたはこれらのいずれかの値を指定でき、パラメータformatを、確認する必要がありますか? RGB_888形式はありません。 Java co C++のビットマップをRGBA_8888ピクセル形式で送信していることを確認して、それに応じてアルゴリズムを変更する必要があります。出力のピクセル形式を32ビット(24ビットではなく)に変更する方が簡単だと思います。

関連する問題