RenderScript से माइग्रेट करें

Android 12 में RenderScript एपीआई बंद कर दिए गए हैं. डिवाइस और कॉम्पोनेंट निर्माताओं ने पहले ही हार्डवेयर से तेज़ी लाने के लिए सहायता देना बंद कर दिया है, और उम्मीद है कि आने वाले समय में रिलीज़ में, RenderScript सपोर्ट को पूरी तरह हटा दिया जाएगा.

C/C++ की परफ़ॉर्मेंस कई तरह के इस्तेमाल के लिए काफ़ी हो सकती है. इसके लिए ज़रूरी है कि Intrinsics के लिए RenderScript पर निर्भर करता है, तो आप उन इस्तेमाल को RenderScript Intrinsics बनने का नया टूलकिट का इस्तेमाल करना. यह ज़्यादा आसान है इसमें 2 गुना सुधार होता है!

अगर आपको जीपीयू से तेज़ी से काम करने की सुविधा का पूरा फ़ायदा लेना है, तो हमारा सुझाव है कि अपनी स्क्रिप्ट को Vulkan पर माइग्रेट करना, तेज़ी से काम करने वाले अन्य विकल्प कैनवस-आधारित टूल का इस्तेमाल करके, अपनी स्क्रिप्ट को OpenGL पर माइग्रेट करना शामिल है इमेज से जुड़ी कार्रवाइयां या Android ग्राफ़िक शेडिंग का इस्तेमाल करके भाषा (एजीएसएल).

Android प्लैटफ़ॉर्म में RenderScript के काम को बंद करने के बाद, 'Android Gradle प्लग इन' से RenderScript को हटाया जा रहा है. इससे शुरू हो रहा है 'Android Gradle प्लग इन 7.2' के साथ-साथ, RenderScript एपीआई अब काम नहीं करते. वे के साथ काम करना जारी रखें, लेकिन चेतावनियों को शुरू करें. एजीपी के आने वाले वर्शन अब बंद हो जाएंगे इसमें 'रेंडरस्क्रिप्ट' की सुविधा भी शामिल है. यह गाइड बताती है कि RenderScript.

स्वाभाविक से माइग्रेट करें

हालांकि RenderScript इंट्रिन्सिक्स फ़ंक्शन RenderScript का इस्तेमाल बंद होने के दौरान, वह जीपीयू.

इनमें से कुछ ऑपरेशन के लिए, अब ज़्यादा बेहतर विकल्प उपलब्ध हैं या Jetpack लाइब्रेरी में मौजूद हों.

बिल्ट-इन ऐक्सेलरेटेड इमेज ऑपरेशन

Android प्लैटफ़ॉर्म पर इमेज प्रोसेसिंग को तेज़ी से किया जा सकता है. इससे ये काम किए जा सकते हैं किसी भी इमेज पर लागू की जा सकती है. यह RenderScript के मूल रूप से अलग नहीं है. उदाहरण के लिए:

  • ब्लेंड
  • धुंधला
  • कलर मैट्रिक्स
  • साइज़ बदलें

Android 12 और उसके बाद के वर्शन पर, इमेज को व्यू के तौर पर धुंधला करने की सुविधा

बैकग्राउंड को धुंधला करने की सुविधा, RenderEffect को Android 12 में जोड़ दिया गया है. एपीआई लेवल 31, जिससे RenderNode को धुंधला किया जा सकता है. RenderNode अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है डिसप्ले सूची का एक फ़ॉर्मैट है जिसका इस्तेमाल Android, तेज़ी से काम करने में मदद करने के लिए करता है प्लैटफ़ॉर्म ग्राफ़िक.

Android, संबंधित RenderNode में इफ़ेक्ट लागू करने का शॉर्टकट देता है View के साथ. View को धुंधला करने के लिए, कॉल करें View.setRenderEffect():

val blurRenderEffect = RenderEffect.createBlurEffect(radius, radius,
        Shader.TileMode.MIRROR
    )
view.setRenderEffect(blurRenderEffect)

Android 12 और उसके बाद के वर्शन पर, इमेज को धुंधला करने के लिए बिटमैप का इस्तेमाल किया गया है

अगर धुंधली इमेज को Bitmap में रेंडर करना है, तो HardwareRenderer की मदद से, तेज़ी से रेंडर होने की सुविधा का इस्तेमाल करता है HardwareBuffer की मदद से बनाया गया है. यह कोड बनाता है धुंधला करने के लिए HardwareRenderer, RenderNode, और RenderEffect:

val imageReader = ImageReader.newInstance(
    bitmap.width, bitmap.height,
    PixelFormat.RGBA_8888, numberOfOutputImages,
    HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_GPU_COLOR_OUTPUT
)
val renderNode = RenderNode("BlurEffect")
val hardwareRenderer = HardwareRenderer()

hardwareRenderer.setSurface(imageReader.surface)
hardwareRenderer.setContentRoot(renderNode)
renderNode.setPosition(0, 0, imageReader.width, imageReader.height)
val blurRenderEffect = RenderEffect.createBlurEffect(
    radius, radius,
    Shader.TileMode.MIRROR
)
renderNode.setRenderEffect(blurRenderEffect)

इफ़ेक्ट को लागू करने के लिए, अंदरूनी RenderNode के लिए RecordingCanvas. यह कोड ड्रॉइंग को रिकॉर्ड करता है, रेंडर करने का अनुरोध बनाता है, और फिर पूरा करने के लिए अनुरोध करें:

val renderCanvas = it.renderNode.beginRecording()
renderCanvas.drawBitmap(it.bitmap, 0f, 0f, null)
renderNode.endRecording()
hardwareRenderer.createRenderRequest()
    .setWaitForPresent(true)
    .syncAndDraw()

रेंडर की गई इमेज, इससे जुड़े HardwareBuffer में है ImageReader. इस कोड से Image और यह Bitmap को दिखाता है, जो अपने HardwareBuffer को रैप करता है.

val image = imageReader.acquireNextImage() ?: throw RuntimeException("No Image")
val hardwareBuffer = image.hardwareBuffer ?: throw RuntimeException("No HardwareBuffer")
val bitmap = Bitmap.wrapHardwareBuffer(hardwareBuffer, null)
    ?: throw RuntimeException("Create Bitmap Failed")

इमेज को रेंडर करने के बाद, नीचे दिया गया कोड सभी क्लीन-अप कर देता है. ध्यान दें कि ImageReader, RenderNode, RenderEffect, और HardwareRenderer का इस्तेमाल किया जा सकता है का इस्तेमाल करें.

hardwareBuffer.close()
image.close()
imageReader.close()
renderNode.discardDisplayList()
hardwareRenderer.destroy()

इमेज प्रोसेसिंग के लिए एजीएसएल

Android 13 और इसके बाद के वर्शन में, Android ग्राफ़िक शेडिंग लैंग्वेज (AGSL) का इस्तेमाल इन कामों के लिए किया जाता है प्रोग्राम करने योग्य व्यवहार को परिभाषित करें RuntimeShader ऑब्जेक्ट. एजीएसएल अपना ज़्यादातर सिंटैक्स GLSL फ़्रैगमेंट शेडर के साथ शेयर करता है, लेकिन Canvas के अंदर पेंटिंग को पसंद के मुताबिक बनाने के लिए, Android ग्राफ़िक रेंडरिंग सिस्टम और View कॉन्टेंट को फ़िल्टर करें. कस्टम इमेज प्रोसेसिंग जोड़ने के लिए, इसका इस्तेमाल किया जा सकता है इस्तेमाल करते समय या सीधे RenderNode का इस्तेमाल करके Bitmap कैनवास में इमेज शामिल करें. नीचे दिए गए उदाहरण में, Google News पर कस्टम शेडर का इस्तेमाल करें.

RuntimeShader बनाकर शुरुआत करें और इसे AGSL शेडर की मदद से इंस्टैंशिएट करें कोड. इस शेडर का इस्तेमाल ह्यू रोटेशन के लिए कलर मैट्रिक्स लागू करने के लिए किया जाता है:

val hueShader = RuntimeShader("""
    uniform float2 iResolution;       // Viewport resolution (pixels)
    uniform float2 iImageResolution;  // iImage1 resolution (pixels)
    uniform float iRadian;            // radian to rotate things around
    uniform shader iImage1;           // An input image
    half4 main(float2 fragCoord) {
    float cosR = cos(iRadian);
    float sinR = sin(iRadian);
        mat4 hueRotation =
        mat4 (
                0.299 + 0.701 * cosR + 0.168 * sinR, //0
                0.587 - 0.587 * cosR + 0.330 * sinR, //1
                0.114 - 0.114 * cosR - 0.497 * sinR, //2
                0.0,                                 //3
                0.299 - 0.299 * cosR - 0.328 * sinR, //4
                0.587 + 0.413 * cosR + 0.035 * sinR, //5
                0.114 - 0.114 * cosR + 0.292 * sinR, //6
                0.0,                                 //7
                0.299 - 0.300 * cosR + 1.25 * sinR,  //8
                0.587 - 0.588 * cosR - 1.05 * sinR,  //9
                0.114 + 0.886 * cosR - 0.203 * sinR, //10
                0.0,                                 //11
                0.0, 0.0, 0.0, 1.0 );                //12,13,14,15
        float2 scale = iImageResolution.xy / iResolution.xy;
        return iImage1.eval(fragCoord * scale)*hueRotation;
    }
""")

शेडर को RenderNode पर लागू किया जा सकता है, जैसा कि किसी अन्य RenderEffect पर लागू किया जाता है. नीचे दिए गए उदाहरण में, hueShader में यूनिफ़ॉर्म को सेट करने का तरीका बताया गया है:

hueShader.setFloatUniform("iImageResolution", bitmap.width.toFloat(),
    bitmap.height.toFloat())
hueShader.setFloatUniform("iResolution", bitmap.width.toFloat(),
    bitmap.height.toFloat())
hueShader.setFloatUniform("iRadian", radian)
hueShader.setInputShader( "iImage1", BitmapShader(bitmap, Shader.TileMode.MIRROR,
    Shader.TileMode.MIRROR))
val colorFilterEffect = RenderEffect.createShaderEffect(it.hueShader)
renderNode.setRenderEffect(colorFilterEffect)

Bitmap पाने के लिए, उसी तकनीक का इस्तेमाल किया जाता है जिसका इस्तेमाल पिछली इमेज ब्लर करने में किया जाता था सैंपल.

  • इंटरनल RenderNode के लिए RecordingCanvas, शेडर लागू करता है.
  • Image को खरीदा गया और उसके जवाब में Bitmap मिला HardwareBuffer.

CameraX का इस्तेमाल करके, प्लानर YUV से RGB में बदलें

planar YUV से बदला जा रहा है को आरजीबी के लिए इमेज प्रोसेसिंग में इस्तेमाल किया जा सकता है. Jetpack में मौजूद ImageAnalysis के इस्तेमाल का उदाहरण CameraX.

यहां कुछ संसाधन दिए गए हैं, जिनके तहत ImageAnalysis को कोडलैब (कोड बनाना सीखना) और कैमराX का इस्तेमाल शुरू करना Android कैमरा सैंपल रिपॉज़िटरी.

'रेंडरस्क्रिप्ट इंट्रिक्सिक्स' रिप्लेसमेंट टूलकिट

अगर आपका ऐप्लिकेशन इंट्रिंसिक्स का इस्तेमाल करता है, तो आपके पास स्टैंडअलोन रिप्लेसमेंट का इस्तेमाल करने का विकल्प होता है लाइब्रेरी; हमारे टेस्ट बताते हैं कि यह मौजूदा RenderScript सीपीयू के इस्तेमाल से ज़्यादा तेज़ है लागू करना.

इस टूलकिट में ये फ़ंक्शन शामिल होते हैं:

  • ब्लेंड
  • धुंधला
  • कलर मैट्रिक्स
  • कन्वर्ज़न
  • हिस्टोग्राम और हिस्टोग्राम डॉट
  • लुकअप टेबल (LUT) और LUT 3D
  • साइज़ बदलें
  • YUV से RGB

ज़्यादा जानकारी और सीमाओं के लिए, टूलकिट के README.md और Toolkit.kt देखें. फ़ाइलें शामिल हैं.

लाइब्रेरी को डाउनलोड करने, जोड़ने, और इस्तेमाल करने के लिए यह तरीका अपनाएं:

  1. प्रोजेक्ट डाउनलोड करें GitHub से लिया गया है.

  2. renderscript-toolkit module ढूंढें और बनाएं.

  3. ऐप्लिकेशन के बदलाव करके, अपने Android Studio प्रोजेक्ट में लाइब्रेरी जोड़ें build.gradle फ़ाइल.

  4. टूलकिट का सही तरीका शुरू करें.

उदाहरण: ScriptIntrinsicBlur फ़ंक्शन से माइग्रेट करना

ScriptIntrinsicBlur फ़ंक्शन को बदलने के लिए:

  • बिट मैप को धुंधला करने के लिए, Toolkit.blur पर कॉल करें.

    var blurredBitmap = Toolkit.blur(myBitmap, radius)
    
  • अगर आप बाइट के कलेक्शन वाली इमेज को धुंधला करना चाहते हैं, तो हर पिक्सल की चौड़ाई, ऊंचाई, और बाइट की संख्या.

    val outArray = Toolkit.blur(inputArray, bytesPerPixel, width, height, radius)
    

स्क्रिप्ट से माइग्रेट करें

अगर ऐप्लिकेशन के इस्तेमाल का उदाहरण इसके साथ हल नहीं किया जा सकता:

साथ ही, जीपीयू का इस्तेमाल करने पर, Android डिवाइस पर जीपीयू के साथ काम करता है की गणना करें. आपको यह विकल्प दिख सकता है इसकी ज़रूरत नहीं है, क्योंकि ज़्यादातर डिवाइस पर आपकी स्क्रिप्ट पहले से ही सीपीयू (CPU) पर चल रही हैं जीपीयू के बजाय: C/C++, RenderScript, GLES या Vulkan से ज़्यादा तेज़ हो सकता है इस्तेमाल के कुछ उदाहरणों के लिए, इसकी वैल्यू को कैलकुलेट करें. (या आपके उपयोग के उदाहरण के हिसाब से, कम से कम इतना तेज़ है)

माइग्रेट करने के तरीके को बेहतर ढंग से समझने के लिए, ऐप्लिकेशन का नमूना. कॉन्टेंट बनाने सैंपल में बिटमैप को धुंधला करने और कलर-मैट्रिक्स कन्वर्ज़न करने, दोनों के तरीके के बारे में बताया गया है के साथ-साथ Vulkan और OpenGL में भी इसके बराबर कोड मौजूद हैं.

अगर आपके ऐप्लिकेशन को रिलीज़ की एक रेंज का समर्थन करना है, तो RenderScript का इस्तेमाल करें Android 6 (एपीआई लेवल 23) और इससे पहले के वर्शन वाले डिवाइसों के साथ-साथ Vulkan या GLES पर काम करते हैं Android 7 (एपीआई लेवल 24) और उसके बाद के वर्शन वाले डिवाइस पर काम करता है. अगर आपके minSdkVersion, 24 या उससे ज़्यादा का है, तो हो सकता है कि आपको RenderScript का इस्तेमाल करने की ज़रूरत न पड़े; Vulkan या जीपीयू कंप्यूट के सपोर्ट की ज़रूरत होने पर, जीएलईएस 3.1 का इस्तेमाल कहीं भी किया जा सकता है.

Android, जीएलईएस एपीआई के लिए एसडीके बाइंडिंग उपलब्ध कराता है. इसलिए, Android, OpenGL ES में काम करते समय NDK.

Vulkan, SDK टूल बाइंडिंग उपलब्ध नहीं कराता है. इसलिए, इसकी कोई डायरेक्ट मैपिंग नहीं है Vulkan को रेंडर करने की स्क्रिप्ट; तो एनडीके का इस्तेमाल करके Vulkan कोड लिखा जाता है और JNI बनाया जाता है Kotlin या Java से इस कोड को ऐक्सेस करने के लिए काम करती है.

नीचे दिए गए पेजों में RenderScript से माइग्रेट करने के पहलुओं को शामिल किया गया है. सैंपल ऐप्लिकेशन में ज़्यादातर इन सभी बातों का ध्यान रखा जाता है. उन्हें बेहतर ढंग से समझने के लिए, RenderScript और Vulkan के मिलते-जुलते कोड की तुलना करें.