2013-08-27 12 views
5

Android Geliştirme için JNI'yi kullanarak Android'den C++'ya bir bitmap aktarmak istiyorum.Android Geliştirme'de JNI ile Java'dan C++'ya bir bitmap nasıl geçilir?

Java'da, ı Java C++ bir Bitmap göndermek için bu işlevi çağırmak:

JNI içinde
public native int sendMyBitmap(Bitmap bitmap); 

, böyle yapmış:

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 bitmap kaydettikten sonra ++ JNI, Java'daki ve C++'daki bitmapler farklıdır. Sorunun ne olduğunu bulmak için uğraşıyorum ve sorunu nasıl bulabilirim.

+0

Lütfen tahmini sonuçları ve gerçek sonuçları buradan bildiriniz. – krsteeve

cevap

3

Bu line: girdi bitmap varsayıyoruz

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

piksel başına 24 sokması (3 bayt) vardır. Ama android'de böyle bir piksel formatı yoktur.

Ayrıca, genişliğin tam olarak 640 piksel olduğunu ve yüksekliğin tam olarak 480 piksel olduğunu varsayorsunuz. Bu sizin durumunuzda doğru olabilir, ancak bu bilgiyi okumalısınız, değerleri kodlamalısınız.

Tüm bu değerler AndroidBitmap_getInfo() işleviyle sağlanır. Neden onları kullanmıyorsun?

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

Doğruca Bitmapin boyutlarını okuyabilir: Sadece yapıyı AndroidBitmapInfo kontrol edin.

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

Görüyorsunuz: Ek olarak bu değerlerden biri olabilir parametreyi format, kontrol etmelisiniz? RGB_888 biçiminde değil. Bitmap'i Java co C++ 'dan RGBA_8888 piksel formatında göndermiş olduğunuzdan emin olmalısınız ve algoritmanızı buna göre değiştirin. Çıktı piksel formatını 32 bite (24 bit yerine) değiştirmenin daha kolay olacağını düşünüyorum.