2013-08-27 5 views
5

Ich möchte eine Bitmap von Android nach C++ mit JNI für Android-Entwicklung übergeben.Wie übergibt man eine Bitmap von Java nach C++ mit JNI in Android Development?

In Java, nenne ich diese Funktion ein Bitmap von Java nach C senden ++:

public native int sendMyBitmap(Bitmap bitmap); 

in JNI, ich habe es so gemacht:

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); 
} 

Nachdem die Bitmap in C Speicher ++ JNI, die Bitmaps in Java und in C++ sind unterschiedlich. Ich kämpfe um herauszufinden, was das Problem ist und wie kann ich das Problem finden.

+0

Bitte beschreiben Sie die erwarteten Ergebnisse gegenüber den tatsächlichen Ergebnissen – krsteeve

Antwort

3

Diese Zeile:

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

Sie sind unter der Annahme der Eingangs BITMAP hat 24 Stiche (3 Byte) pro Pixel. Aber es gibt kein solches Pixelformat in Android.

Sie gehen auch davon aus, dass die Breite genau 640 Pixel und die Höhe genau 480 Pixel beträgt. Dies kann in Ihrem Fall die Wahrheit sein, aber Sie sollten diese Informationen lesen, nicht die Werte hardcodieren. Alle Werte werden von der Funktion AndroidBitmap_getInfo() zur Verfügung gestellt. Warum benutzt du sie nicht? AndroidBitmapInfo Überprüfen Sie einfach die Struktur:

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

Sie können direkt die Maße Ihres Bitmap lesen. Zusätzlich sollten Sie die Parameter überprüfen format, die einer dieser Werte sein kann:

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, 
}; 

Sie sehen? Es gibt kein RGB_888 Format. Sie sollten sicherstellen, dass Sie die Bitmap im RGBA_8888 Pixelformat von Java mit C++ senden und Ihren Algorithmus entsprechend ändern. Ich denke, es wäre einfacher, das Ausgabe-Pixelformat auf 32 Bit (statt 24 Bit) zu ändern.

Verwandte Themen