2016-06-17 4 views
1

C에서이 안드로이드 코드를 변환하는 데 도움을 주시기 바랍니다.이 부분은 C NDK에서하고 싶습니다. 여기에 내가 지금까지 시도한 것이있다. 나는 getPixel()setPixel()을 android로 변환 할 수 없다. 아래 코드를 참조하십시오. @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 비트 맵을 사용하는 캔버스에서만 그리기를 통해 자바 코드로 할 수 있습니다. 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 가장 간단한 방법은 비트 맵 생성 - 자바에서 그것을 수행 한 다음 네이티브 코드에 인수로 전달하는 것입니다. 또는 JNEnv 메소드 (http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html#wp20949)를 통해 네이티브에서 동일한 권한을 얻을 수 있습니다. – Sergio