2011-10-01 14 views
6

मैं एक्शन एंड्रॉइड इन एक्शन (2 संस्करण) से लिया गया कोड का एक टुकड़ा उपयोग करके, एक छवि को ग्रेस्केल में एक देशी फ़ंक्शन के माध्यम से कनवर्ट करने का प्रयास कर रहा हूं, आप इसे here भी देख सकते हैं)। दुर्भाग्य से, ग्रेस्केल की बजाय लौटाई गई बिटमैप ऑब्जेक्ट खाली हो जाती है।मूल बिटमैप प्रोसेसिंग और ALPHA_8

यह कैसे मैं (.png) छवि को लोड है:

Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options); 

वहाँ सुरक्षा की स्थिति की एक संख्या है कि बिटमैप गुजरता है (नीचे की जाँच करें)।

public native void convertToGray(Bitmap bitmapIn,Bitmap bitmapOut); 

और कॉल:

// Grayscale bitmap (initially empty)  
Bitmap gray = Bitmap.createBitmap(original.getWidth(),original.getHeight(),Config.ALPHA_8); 
// Native function call 
convertToGray(original,gray); 

और यहाँ समारोह है:

JNIEXPORT void JNICALL Java_com_example_Preprocessor_convertToGray(JNIEnv * env, jobject obj, jobject bitmapcolor,jobject bitmapgray) 
{ 
    AndroidBitmapInfo infocolor; 
    AndroidBitmapInfo infogray; 
    void* pixelscolor; 
    void* pixelsgray; 
    int ret; 
    int y; 
    int x;  

    LOGI("convertToGray"); 
    if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) { 
     LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 
     return; 
    }  

    if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) { 
     LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 
     return; 
    } 

    LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags); 
    if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) { 
     LOGE("Bitmap format is not RGBA_8888 !"); 
     return; 
    } 

    LOGI("gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infogray.width,infogray.height,infogray.stride,infogray.format,infogray.flags); 
    if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) { 
     LOGE("Bitmap format is not A_8 !"); 
     return; 
    } 

    if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) { 
     LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 
    } 

    if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) { 
     LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); 
    } 

    // modify pixels with image processing algorithm 
    for (y=0;y<infocolor.height;y++) { 
     argb * line = (argb *) pixelscolor; 
     uint8_t * grayline = (uint8_t *) pixelsgray; 
     for (x=0;x<infocolor.width;x++) { 
      grayline[x] = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue; 
     } 

     pixelscolor = (char *)pixelscolor + infocolor.stride; 
     pixelsgray = (char *) pixelsgray + infogray.stride; 
    } 

    LOGI("Done! Unlocking pixels..."); 
    AndroidBitmap_unlockPixels(env, bitmapcolor); 
    AndroidBitmap_unlockPixels(env, bitmapgray); 
} 

रंग बिटमैप सही ढंग से पारित कर दिया जाता है, और के प्रसंस्करण हिस्सा यहाँ जावा में देशी समारोह परिभाषा है कोड ठीक काम करता प्रतीत होता है, लेकिन बिटमैप्रे खाली रहता है। मुझे लगता है कि मैं यहां कुछ महत्वपूर्ण याद कर रहा हूं।

परीक्षण पर्यावरण: एम्यूलेटर, v2.2। इस संस्करण के साथ, फ़ंक्शन काम करता है जब मूल कोड मुख्य थ्रेड से कहा जाता है। 2.3 एमुलेटर पर, फ़ंक्शन पर काम नहीं करता है, भले ही पर ध्यान दें जो सी कोड को कॉल करता है, या जिस तरह बिटमैप लोड होता है। एंड्रॉइड एनडीके: 4 बी & 6 बी।

अद्यतन # 1: आप पूरा स्रोत कोड here मिल जाएगा।

UPDATE # 2: ALPHA_8 के बजाय RGB_565 कुछ परिणाम देता है। ऐसा लगता है कि Java में setPixels() भी ALPHA_8 के लिए काम करता है, और मेरे पास इस कॉन्फ़िगरेशन प्रकार पर जानकारी ढूंढने में समस्याएं हैं। किसी भी तरह की मदद बहुत सराहना की जाएगी।

+0

आप आउटपुट के रूप में एक ByteBuffer उपयोग करने की कोशिश माना जाता है? यदि यह काम करता है, तो हम और अधिक सुनिश्चित हो सकते हैं कि AndroidBitmap के साथ कुछ गड़बड़ है ... 'bitmapIn', 'bitmapOrig' और' original' एक ही ऑब्जेक्ट भी हैं? –

+0

मैं जेएनआई के लिए बिल्कुल नया हूं, इसलिए नहीं, मैंने कोशिश नहीं की है। मैं इसे एक शॉट दूंगा और फिर वापस रिपोर्ट करूंगा। मैं अभी भी कुछ सुझावों या दिशाओं के लिए आभारी हूं जो प्रक्रिया को तेज कर सकते हैं। और, हाँ, bitmapIn = bitmapOrig = मूल (बाद वाले दो के बारे में खेद है; मुझे इसे स्पष्ट करना चाहिए था; इसे ठीक करें)। –

+0

@ सैमुएलऑडेट: ठीक है, मैंने कोशिश की [यह एक] (http://imrannazar.com/Agmented-Reality-with-the-Android-NDK:- भाग -2)। नतीजा एक * लगभग * खाली बिटमैप (काला कलाकृतियों (यादृच्छिक काला बिंदु) के साथ एक सफेद सतह है)। क्या कोई और यह शॉट देने के लिए पर्याप्त दयालु होगा? –

उत्तर

1

मुझे भी इसी तरह की समस्या थी। सबसे पहले, मैंने A_8 के बजाय इंफोग्रे के लिए एंड्रॉइड RGBA_8888 प्रारूप का उपयोग किया (मूल बिटमैप ARGB_8888 प्रारूप का उपयोग करके बनाया गया था)। तो अगर आप uint_8 के बजाय Grayline के लिए struct ARGB उपयोग करते हैं, आप पिक्सल इस तरह भर सकते हैं:

for (y = 0; y < infocolor.height; ++y) { 
     argb* line = (argb*) pixelscolor; 
     argb* grayline = (argb*) pixelsgray; 
     for (x = 0; x < infocolor.width; ++x) {   
      grayline[x].red = grayline[x].green = grayline[x].blue = 0.3 * line[x].red + 0.59 * line[x].green + 0.11 * line[x].blue; 
     } 
     pixelscolor = (char*)pixelscolor + infocolor.stride; 
     pixelsgray = (char*)pixelsgray + infogray.stride; 
    } 
+0

अच्छा, यह कुछ परिणाम देता है, लेकिन आउटपुट छवि नीली है। मैं कुछ स्मृति को बचाने के लिए A_8 का उपयोग करने की उम्मीद कर रहा था (मैं कुछ वास्तविक समय छवि प्रसंस्करण का प्रयास करना चाहता हूं)। –

1

मैं एक ही समस्या थी। मैंने ALPHA_8 काम करने के लिए बहुत कुछ नहीं किया लेकिन ARGB_8888 का उपयोग समस्या को हल करता है।

Btw, @ white_pawn की टिप्पणी के जवाब में (खेद है कि मैं टिप्पणियों का जवाब नहीं कर सकते हैं)

IBM's उदाहरण में ARGB struct गलत क्रम में है। मेरे अनुकरणकर्ताओं या फोन में, इसे आरजीबीए में परिवर्तित करने से समस्या ठीक हो जाती है (शायद यही कारण है कि आपकी छवि नीली दिखती है क्योंकि आप नीले रंग के लिए अल्पा का उपयोग करते हैं)। हालांकि मुझे यकीन नहीं है कि यह आदेश हार्डवेयर निर्भर है या नहीं।

typedef struct 
{ 
    uint8_t red; 
    uint8_t green; 
    uint8_t blue; 
    uint8_t alpha; 
} argb; 
0

मुझे एक ही समस्या थी और पता चला कि क्या गलत हुआ!आप APHA_8 का उपयोग करते हैं आप #ffffffff करने के लिए पृष्ठभूमि बदलने की जरूरत है,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:background="#ffffffff"> 
संबंधित मुद्दे