2016-06-17 3 views
1

Cでこのアンドロイドコードを変換する際に助けてください。私はこの部分をC NDKで使いたいと思います。これまで私が試したことがあります。私はgetPixel()setPixel()をアンドロイドの方法に変換できません。以下のコードをご覧ください。私はこの方法を書いた@Serhioの助けを借りてアンドロイドでアンドロイドコードをcに変換するNDK

JNIEXPORT jobject JNICALL 
Java_com_test_mypic_StylePreviewActivity_mergeBitmaps(JNIEnv *env, jobject instance, 
                     jobject bm, jobject filter) { 
    AndroidBitmapInfo bm1; 
    AndroidBitmap_getInfo(env, bm, &bm1); 

    AndroidBitmapInfo filter1; 
    AndroidBitmap_getInfo(env, filter, &filter1); 

    int width = bm1.width; 
    int height = bm1.height; 
    int w2 = filter1.width; 
    int h2 = filter1.height; 
    float scaleX = (float) w2/(float) width; 

    Bitmap result = Bitmap.createBitmap(w2, h2, ANDROID_BITMAP_FORMAT_RGB_565); 

    void* bitmapPixels; 
    AndroidBitmap_lockPixels(env, bm, &bitmapPixels); 

    for (int x = 0; x < w2; x++) { 
     for (int y = 0; y < h2 && y < height; y++) { 
      int xx =(int) ((float) x/scaleX); 
      int yy = (int) ((float) y/scaleX); 
      int pixel = bm1.getPixel(xx, yy); 
      int fp = filter1.getPixel(x, y); 

      int alpha = (fp & 0xFF000000) >> 24; 

      if (alpha == 0) { 
       result.setPixel(x, y, pixel); 
      } 
     } 
    } 
    result = Bitmap.createBitmap(result, 0, 0, width, height); 
    return result; 
} 

。しかし、ここに何か が間違っているようです。何人かはこれをチェックしてください。

JNIEXPORT jobject JNICALL 
Java_com_test_mypic_StylePreviewActivity_mergeBitmaps(JNIEnv *env, jobject instance, 
                     jobject bm, jobject filter, jobject result) { 
    AndroidBitmapInfo bm1; 
    AndroidBitmap_getInfo(env, bm, &bm1); 

    AndroidBitmapInfo filter1; 
    AndroidBitmap_getInfo(env, filter, &filter1); 

// AndroidBitmapInfo result1; 
// AndroidBitmap_getInfo(env, result, &result1); 

    int width = bm1.width; 
    int height = bm1.height; 
    int w2 = filter1.width; 
    int h2 = filter1.height; 
    float scaleX = (float) w2/(float) width; 

    for (int x = 0; x < w2; x++) { 
     for (int y = 0; y < h2 && y < height; y++) { 
      int xx =(int) ((float) x/scaleX); 
      int yy = (int) ((float) y/scaleX); 
      int pixel = getPixel(env,bm, xx, yy); 
      int fp = getPixel(env,filter,x, y); 

      int alpha = (fp & 0xFF000000) >> 24; 

      if (alpha == 0) { 
       setPixel(env, result, x, y, pixel); 
      } 
     } 
    } 

    return result; 
} 

答えて

1

ネイティブコードでgetPixel()/setPixel()にはストレートアナログはありません。これに代えて、AndroidBitmap_lockPixels()を介して未処理のピクセル・ポインタ・バッファを取得し、このバッファ内のデータを自由に変更できます。 /設定された単一のピクセルを取得するには、次の機能を使用することができます。もちろん

#include <stdint.h> 
#include <assert.h> 
#include <jni.h> 
#include <android/bitmap.h> 

uint32_t getPixel(JNIEnv *env, jobject bm, int x, int y) 
{ 
    AndroidBitmapInfo bi = {0}; 
    uint8_t *pixelBuf; 
    uint8_t a, r, g, b; 

    AndroidBitmap_getInfo(env, bm, &bi); 
    /* ensure that we fit into bounds */ 
    assert(x >= 0 && x < bi.width 
      && y >= 0 && y < bi.height); 
    /* we support only one format at the moment */ 
    assert(ANDROID_BITMAP_FORMAT_RGBA_8888 == bi.format); 
    /* read pixel components */ 
    AndroidBitmap_lockPixels(env, bm, (void **)&pixelBuf); 
    r = pixelBuf[y * bi.stride + x * 4 + 0]; 
    g = pixelBuf[y * bi.stride + x * 4 + 1]; 
    b = pixelBuf[y * bi.stride + x * 4 + 2]; 
    a = pixelBuf[y * bi.stride + x * 4 + 3]; 
    AndroidBitmap_unlockPixels(env, bm); 
    return a << 24 | r << 16 | g << 8 | b; 
} 

void setPixel(JNIEnv *env, jobject bm, int x, int y, uint32_t val) 
{ 
    AndroidBitmapInfo bi = {0}; 
    uint8_t *pixelBuf; 

    AndroidBitmap_getInfo(env, bm, &bi); 
    /* ensure that we fit into bounds */ 
    assert(x >= 0 && x < bi.width 
      && y >= 0 && y < bi.height); 
    /* we support only one format at the moment */ 
    assert(ANDROID_BITMAP_FORMAT_RGBA_8888 == bi.format); 
    /* read pixel components */ 
    AndroidBitmap_lockPixels(env, bm, (void **)&pixelBuf); 
    pixelBuf[y * bi.stride + x * 4 + 0] = (val >> 16) & 0xff; 
    pixelBuf[y * bi.stride + x * 4 + 1] = (val >> 8) & 0xff; 
    pixelBuf[y * bi.stride + x * 4 + 2] = (val >> 0) & 0xff; 
    pixelBuf[y * bi.stride + x * 4 + 3] = (val >> 24) & 0xff; 
    AndroidBitmap_unlockPixels(env, bm); 
} 

をあなたは一度だけバッファをロックし、ループ内のピクセルを反復処理することができます。

あなたのコードはビットマップにマスクを適用する必要があります。おそらく、適切なPorterDuffXfermodeのビットマップパワードキャンバス上の描画を介してJavaコードで行うことは可能です。 See here。それはネイティブコードで行われるので、パフォーマンスは良いでしょう。

+0

ありがとうございます@serhio。このメソッドの変換にも協力してください。Bitmap result = Bitmap.createBitmap(w2、h2、ANDROID_BITMAP_FORMAT_RGB_565);上記のコードを参照してください。 – sanidhya09

+0

また、このコードを手伝っていただければ幸いです。 @serhio http://stackoverflow.com/questions/37959067/ndk-code-crashing-in-few-htc-lollipop-devices-and-few-other-devices-by-giving-fa – sanidhya09

+0

@ sanidhya09最も簡単な方法はビットマップを作成する - それをjavaで行い、それをネイティブコードの引数として渡します。あるいは、JNEnvのメソッドhttp://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp20949を使用してネイティブで同じ権利を達成することもできます。 – Sergio

関連する問題