2017-08-30 8 views
7

के गलत तरीके से मैनिपुलेट करने का प्रयास कर रहा हूं, मैं एक छवि के पीछे अर्ध-पारदर्शी सर्कल प्रस्तुत करने के लिए एंड्रॉइड के रेंडरस्क्रिप्ट का उपयोग करने की कोशिश कर रहा हूं, लेकिन रेंडरस्क्रिप्ट कर्नेल से मूल्य लौटने पर चीजें बहुत गलत होती हैं।रेंडरस्क्रिप्ट कर्नेल

#pragma version(1) 
#pragma rs java_package_name(be.abyx.aurora) 
// We don't need very high precision floating points 
#pragma rs_fp_relaxed 

// Center position of the circle 
int centerX = 0; 
int centerY = 0; 

// Radius of the circle 
int radius = 0; 

// Destination colour of the background can be set here. 
float destinationR; 
float destinationG; 
float destinationB; 
float destinationA; 

static int square(int input) { 
    return input * input; 
} 

uchar4 RS_KERNEL circleRender(uchar4 in, uint32_t x, uint32_t y) { 
    //Convert input uchar4 to float4 
    float4 f4 = rsUnpackColor8888(in); 

    // Check if the current coordinates fall inside the circle 
    if (square(x - centerX) + square(y - centerY) < square(radius)) { 
     // Check if current position is transparent, we then need to add the background!) 
     if (f4.a == 0) { 
      uchar4 temp = rsPackColorTo8888(0.686f, 0.686f, 0.686f, 0.561f); 
      return temp; 
     } 
    } 

    return rsPackColorTo8888(f4); 
} 

अब, rsPackColorTo8888() समारोह 0.0 और 1.0 के बीच एक मूल्य के साथ 4 तैरता लेता है:

यह मेरा गिरी है। परिणामस्वरूप एआरजीबी-रंग तब प्रत्येक फ्लोट वैल्यू के 255 गुणा की गणना करके पाया जाता है। तो दिया तैरता रंग आर के अनुरूप = 0.686 * 255 = 175, जी = 0.686 * 255 = 175, बी = 0.686 * 255 = 175 और एक = 0,561 * 255 = 143.

rsPackColorTo8888() समारोह में ही ठीक से काम करता , लेकिन जब पाया गया uchar4 मान कर्नेल से वापस किया जाता है, तो वास्तव में कुछ अजीब होता है। आर, जी और बी मूल्य परिवर्तन करने के लिए क्रमश: लाल * अल्फा = 56, ग्रीन * अल्फा = 56 और ब्लू * अल्फा = 56 जहां अल्फा 0.561 है। इसका मतलब है कि आर, जी और बी का कोई भी मूल्य ए = 0.561 * 255 से बड़ा नहीं हो सकता है।

rsPackColorTo8888() का उपयोग करने के बजाय मैन्युअल रूप से आउटपुट सेट करना वही व्यवहार उत्पन्न करता है। मेरा मतलब है कि निम्नलिखित कोड ठीक उसी परिणाम, जो बारी में सबूत है कि rsPackColorTo8888() समस्या नहीं है का उत्पादन:

if (square(x - centerX) + square(y - centerY) < square(radius)) { 
    // Check if current position is transparent, we then need to add the background!) 
    if (f4.a == 0) { 
     uchar4 temp; 
     temp[0] = 175; 
     temp[1] = 175; 
     temp[2] = 175; 
     temp[3] = 143; 
     return temp; 
    } 
} 

यह जावा कोड स्क्रिप्ट कहा जाता है, जो है:

@Override 
public Bitmap renderParallel(Bitmap input, int backgroundColour, int padding) { 
    ResizeUtility resizeUtility = new ResizeUtility(); 

    // We want to end up with a square Bitmap with some padding applied to it, so we use the 
    // the length of the largest dimension (width or height) as the width of our square. 
    int dimension = resizeUtility.getLargestDimension(input.getWidth(), input.getHeight()) + 2 * padding; 

    Bitmap output = resizeUtility.createSquareBitmapWithPadding(input, padding); 
    output.setHasAlpha(true); 

    RenderScript rs = RenderScript.create(this.context); 

    Allocation inputAlloc = Allocation.createFromBitmap(rs, output); 
    Type t = inputAlloc.getType(); 

    Allocation outputAlloc = Allocation.createTyped(rs, t); 

    ScriptC_circle_render circleRenderer = new ScriptC_circle_render(rs); 

    circleRenderer.set_centerX(dimension/2); 
    circleRenderer.set_centerY(dimension/2); 
    circleRenderer.set_radius(dimension/2); 
    circleRenderer.set_destinationA(((float) Color.alpha(backgroundColour))/255.0f); 
    circleRenderer.set_destinationR(((float) Color.red(backgroundColour))/255.0f); 
    circleRenderer.set_destinationG(((float) Color.green(backgroundColour))/255.0f); 
    circleRenderer.set_destinationB(((float) Color.blue(backgroundColour))/255.0f); 

    circleRenderer.forEach_circleRender(inputAlloc, outputAlloc); 
    outputAlloc.copyTo(output); 

    inputAlloc.destroy(); 
    outputAlloc.destroy(); 
    circleRenderer.destroy(); 
    rs.destroy(); 

    return output; 
} 

जब अल्फा (एक नाव के रूप में या 1.0) 255 पर सेट है, लौटे रंग-मूल्यों (अपने आवेदन के जावा कोड के अंदर) सही हैं।

मैं कुछ गलत कर रहा हूँ, या यह वास्तव में एक बग RenderScript-कार्यान्वयन में कहीं है?

नोट: मैं जाँच की और एक OnePlus 3T (एंड्रॉयड 7.1.1), एक नेक्सस 5 (एंड्रॉयड 7.1.2), एंड्रॉयड-एमुलेटर संस्करण 7.1.2 और 6.0

+0

क्या आप अपना जावा कोड साझा कर सकते हैं और आप किस डिवाइस पर परीक्षण कर रहे हैं? – sakridge

+0

@sakridge उत्तर देने के लिए धन्यवाद! मैंने जावा-कोड और डिवाइस को जोड़ा है जो मैंने अपनी पोस्ट में परीक्षण के लिए उपयोग किया था। –

+0

मैं निश्चित नहीं हूं, लेकिन शायद 'fa.a == 0' तुलना झूठी का मूल्यांकन करती है क्योंकि 'fa.a' फ़्लोट है। यदि आप 'in.a == 0' में बदलते हैं, तो क्या यह समान आउटपुट उत्पन्न करता है? –

उत्तर

0

के बजाय पर इस व्यवहार की पुष्टि कर लें प्रकार के साथ मूल्यों को पारित करना:

uchar4 temp = rsPackColorTo8888(0.686f, 0.686f, 0.686f, 0.561f); 

फ़्लोट 4 बनाने और इसे पारित करने का प्रयास करना।

float4 newFloat4 = { 0.686, 0.686, 0.686, 0.561 }; 
uchar4 temp = rsPackColorTo8888(newFloat4); 
संबंधित मुद्दे