我正在尝试进入渲染脚本并且对分配使用感到困惑。几乎所有示例都显示了下一个算法:

  • 创建输入和输出位图
  • 从 Bitmaps In 和 Out 对应创建 In 和 Out 分配
  • 配置脚本并执行 forEach 方法
  • 使用 copyTo 方法将 Out 分配的结果复制到位图中

  • 类似的东西:
        Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lena);
        Bitmap dstBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
    
        Allocation allocationIn = Allocation.createFromBitmap(renderScript, srcBitmap);
        Allocation allocationOut = Allocation.createFromBitmap(renderScript, dstBitmap);
    
        scriptColorMatrix.setGreyscale();
    
        scriptColorMatrix.forEach(allocationIn, allocationOut);
    
        //no difference after removing this line
        allocationOut.copyTo(dstBitmap);
    
        imagePreview.setImageBitmap(dstBitmap);
    

    这有效,但即使我通过删除来省略第 4 步,它也有效:
    allocationOut.copyTo(dstBitmap);
    

    让我们更进一步,降低灰度后的亮度:
        Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lena);
        Bitmap dstBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
    
        Allocation allocationIn = Allocation.createFromBitmap(renderScript, srcBitmap);
        Allocation allocationOut = Allocation.createFromBitmap(renderScript, dstBitmap);
    
        scriptColorMatrix.setGreyscale();
    
        scriptColorMatrix.forEach(allocationIn, allocationOut);
    
        //reset color matrix
        scriptColorMatrix.setColorMatrix(new Matrix4f());
    
        //adjust brightness
        scriptColorMatrix.setAdd(-0.5f, -0.5f, -0.5f, 0f);
    
        //Performing forEach vise versa (from out to in)
        scriptColorMatrix.forEach(allocationOut, allocationIn);
    
        imagePreview.setImageBitmap(srcBitmap);
    

    简单描述上面的代码,我们进行了从In分配到Out one的灰度颜色矩阵,以及向后方向的亮度调整。我从来没有调用过 copyTo 方法,但最后我在 srcBitmap 中得到了结果并且它是正确的。

    那不是结束。让我们更深入。我只会留下一张位图和一张分配:
        Bitmap srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lena);
    
        Allocation allocationIn = Allocation.createFromBitmap(renderScript, srcBitmap);
    
        scriptColorMatrix.setGreyscale();
    
        scriptColorMatrix.forEach(allocationIn, allocationIn);
    
        //reset color matrix
        scriptColorMatrix.setColorMatrix(new Matrix4f());
    
        //adjust brightness
        scriptColorMatrix.setAdd(-0.5f, -0.5f, -0.5f, 0f);
    
        scriptColorMatrix.forEach(allocationIn, allocationIn);
    
        imagePreview.setImageBitmap(srcBitmap);
    

    结果是一样的...

    任何人都可以解释为什么会发生这种情况以及在哪里使用 copyTo 以及我可以在没有它的情况下使用定位 Bitmap 吗?

    最佳答案

    需要 Allocation 对象才能将 Bitmap 正确映射到 Renderscript 理解的内容。如果您的目标是 API 18 或更高版本,您正在使用的 Allocation.createFromBitmap() 方法会自动提供标志 USAGE_SHARED ,它试图让 Allocation 使用与 Bitmap 对象相同的后备内存。所以两者是链接的,但从技术上讲,仍然需要 copyTo() 方法,因为 RS 实现可能需要将其同步回来。在某些平台上,这可能已经发生,而其他平台可能会导致暂停,因为 DMA 或其他机制正在使用 RS 代码所做的任何更改更新 Bitmap 的后备内存。

    至于为什么您可以在调用脚本时反转输入/输出 Allocation 顺序 - 它是有效的,由您来获得正确的参数和顺序。对 RS 而言,它们只是指向要操作的某种类型的支持数据的对象。由于两者都是通过 Allocation.createFromBitmap() 调用创建的,因此只要 Bitmap 对象是可变的,它们就可以用作输入或输出。

    同样,输入和输出使用相同的Allocation是不正常的,也不是无效的。这只是意味着您的输入正在即时更改。只要您的脚本在为特定 Element 调用根函数时没有访问数据中的其他 Element ,那么它就应该可以工作(如您所见。)

    10-08 18:26