从位图分配Renderscript

Vin*_*ile 2 android renderscript

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

  1. 创建进出位图
  2. 相应地从位图输入和输出创建输入和输出分配
  3. 配置脚本并执行forEach方法
  4. 使用copyTo方法将Out 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);
Run Code Online (Sandbox Code Playgroud)

这有效,但即使我通过删除省略步骤4也可以工作:

allocationOut.copyTo(dstBitmap);
Run Code Online (Sandbox Code Playgroud)

让我们进一步降低灰度后的亮度:

    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);
Run Code Online (Sandbox Code Playgroud)

简单描述上面的代码,我们执行了从In allocation到Out one的灰度collor矩阵,以及向后方向的亮度调整.我从来没有调用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);
Run Code Online (Sandbox Code Playgroud)

结果是一样的...



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

Lar*_*fer 7

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

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

同样,使用相同Allocation的输入和输出是不正常的,但也不是无效的.它只是意味着您的输入正在快速变化.只要你的脚本Element在为特定的函数调用root函数时没有访问数据中的其他s Element,那么它应该可以工作(正如你所看到的那样).