2012-05-14 26 views
10

मुझे पता चला कि रेंडरस्क्रिप्ट में अच्छा प्रलेखन की कमी है, जो मुझे पता है, forEach आरएस में आवंटन में प्रत्येक व्यक्तिगत आइटम के लिए रूट() निष्पादित करना है।रेंडरस्क्रिप्ट कंप्यूट में आरएसएफरएच करने के लिए एआर पास करना

मैं रेंडरस्क्रिप्ट के लिए लाइब्रेरी बनाने की कोशिश कर रहा हूं जो एक प्रारंभिक बिंदु के रूप में छवि प्रसंस्करण करता है, मैं इस great answer पर पहुंच गया। लेकिन समस्या यह है कि धुंधला ऑपरेशन प्रत्येक पिक्सेल पर है और प्रत्येक पिक्सेल को गणना के दूसरे लूप (एन ब्लर चौड़ाई के साथ) की आवश्यकता होती है। हालांकि बहु-कोर पर चल रहा है, यह अभी भी थोड़ा धीमा है।

मैं इसे (दो-पास) बॉक्स फ़िल्टर की अनुमति देने के लिए संशोधित करने की कोशिश कर रहा हूं, लेकिन इसके लिए सेल की बजाय एक पंक्ति या कॉलम पर काम करने की आवश्यकता है। तो, रूट() को सरणी भेजने के लिए foreach पूछने का कोई तरीका है?

+0

आप क्षैतिज और ऊर्ध्वाधर कलंक के लिए 2 स्क्रिप्ट हो सकता है

यहाँ कुछ RenderScript कि यह दिखाने है। http://stackoverflow.com/questions/13435561/android-blur-bitmap-instantly –

उत्तर

16

rsForEach केवल आवंटन पर ही काम कर सकता है।

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

एक तरीका आप ऐसा कर सकते हैं जो आवंटन में गुजर रहा है जो छवि पंक्तियों के ऑफसेट (छवि डेटा सरणी के भीतर) देता है। रूट() के अंदर v_in तर्क तब पंक्ति ऑफसेट होगा। चूंकि आवंटन rsForEach कॉल चालू है, वह छवि डेटा नहीं है, आप v_out तर्क का उपयोग करके छवि को नहीं लिख सकते हैं और आपको आउटपुट छवि को अलग से बांधना होगा।

#pragma version(1) 
#pragma rs java_package_name(com.android.example.hellocompute) 

rs_allocation gIn; 
rs_allocation gOut; 
rs_script gScript; 

int mImageWidth; 
const uchar4 *gInPixels; 
uchar4 *gOutPixels; 

void init() { 
} 

static const int kBlurWidth = 20; 

// 
// This is called per row. 
// The row indices are passed in as v_in or you could also use the x argument and multiply it by image width. 
// 
void root(const int32_t *v_in, int32_t *v_out, const void *usrData, uint32_t x, uint32_t y) { 
    float3 blur[kBlurWidth]; 
    float3 cur_colour = {0.0f, 0.0f, 0.0f}; 

    for (int i = 0; i < kBlurWidth; i++) { 
     float3 init_colour = {0.0f, 0.0f, 0.0f}; 
     blur[i] = init_colour; 
    } 

    int32_t row_index = *v_in; 
    int blur_index = 0; 

    for (int i = 0; i < mImageWidth; i++) { 
     float4 pixel_colour = rsUnpackColor8888(gInPixels[i + row_index]); 

     cur_colour -= blur[blur_index]; 
     blur[blur_index] = pixel_colour.rgb; 
     cur_colour += blur[blur_index]; 

     blur_index += 1; 
     if (blur_index >= kBlurWidth) { 
      blur_index = 0; 
     } 

     gOutPixels[i + row_index] = rsPackColorTo8888(cur_colour/(float)kBlurWidth); 
     //gOutPixels[i + row_index] = rsPackColorTo8888(pixel_colour); 
    } 
} 


void filter() { 
    rsDebug("Number of rows:", rsAllocationGetDimX(gIn)); 
    rsForEach(gScript, gIn, gOut, NULL); 
} 

यह निम्न जावा का उपयोग करके सेटअप होगा::

mBlurRowScript = new ScriptC_blur_row(mRS, getResources(), R.raw.blur_row); 

    int row_width = mBitmapIn.getWidth(); 

    // 
    // Create an allocation that indexes each row. 
    // 
    int num_rows = mBitmapIn.getHeight(); 
    int[] row_indices = new int[num_rows]; 
    for (int i = 0; i < num_rows; i++) { 
     row_indices[i] = i * row_width; 
    } 
    Allocation row_indices_alloc = Allocation.createSized(mRS, Element.I32(mRS), num_rows, Allocation.USAGE_SCRIPT); 
    row_indices_alloc.copyFrom(row_indices); 

    // 
    // The image data has to be bound to the pointers within the RenderScript so it can be accessed 
    // from the root() function. 
    // 
    mBlurRowScript.bind_gInPixels(mInAllocation); 
    mBlurRowScript.bind_gOutPixels(mOutAllocation); 

    // Pass in the image width 
    mBlurRowScript.set_mImageWidth(row_width); 

    // 
    // Pass in the row indices Allocation as the input. It is also passed in as the output though the output is not used. 
    // 
    mBlurRowScript.set_gIn(row_indices_alloc); 
    mBlurRowScript.set_gOut(row_indices_alloc); 
    mBlurRowScript.set_gScript(mBlurRowScript); 
    mBlurRowScript.invoke_filter(); 
+0

+100 यह इतना चालाक है, कभी नकली करने के लिए "इंडेक्स" पास करने का विचार नहीं किया। – xandy

+0

मैं इस स्क्रिप्ट के लिए "rsForEach" पर कॉल करने के लिए "कोई मिलान करने वाला फ़ंक्शन नहीं" रखता हूं। कैसे? त्रुटि पर अगली पंक्तियां हैं: "... नोट: उम्मीदवार कार्य व्यवहार्य नहीं है: 3 तर्कों की आवश्यकता है, लेकिन 4 प्रदान किए गए थे ... नोट: उम्मीदवार कार्य व्यवहार्य नहीं है: 5 तर्कों की आवश्यकता है, लेकिन 4 प्रदान किए गए थे ... नोट: उम्मीदवार कार्य व्यवहार्य नहीं है: 6 तर्कों की आवश्यकता है, लेकिन 4 प्रदान किए गए थे " –

+1

यह विधि अब और काम नहीं करती है क्योंकि" एपीआई 20+ केवल सरल 1 डी आवंटन को बाइंड के साथ उपयोग करने की अनुमति देता है "(त्रुटि संदेश से उद्धरण)। इसलिए mBlurRowScript.bind_gInPixels (mInAllocation); विफल रहता है। – Searles