I'm trying to get into render script and was confused regarding allocations usage. Almost all examples show next algorithm:
Something like that:
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);
This works, but it also works even if I omit step 4 by removing:
allocationOut.copyTo(dstBitmap);
Lets go further and lower brightness after grayscale:
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);
Shortly describing the code above, we performed grayscale collor matrix from In allocation into Out one, and brightness adjustment in backward direction. I never called copyTo method, but at the end I've got result in srcBitmap and it was correct.
That's not the end. Lets go deeper. I'll leave only one bitmap and one Allocation:
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);
The result is the same...
Can anybody explain why does it happen and where to use copyTo and where I can use targeting Bitmap without it?
答案 0 :(得分:6)
需要Allocation
个对象才能提供Bitmap
到Renderscript理解的内容的正确映射。如果您的目标是API 18或更高版本,则您使用的Allocation.createFromBitmap()
方法会自动提供标记USAGE_SHARED
,该标记会尝试让Allocation
使用与{Bitmap
相同的后备内存1}}对象。所以两者是链接的,但从技术上讲,仍然需要copyTo()
方法,因为RS实现可能需要将其同步回来。在某些平台上,这可能已经发生,其他人可能会因为DMA或其他机制正在使用RS代码所做的任何更改来更新Bitmap
的后备内存而暂停。
至于为什么你可以在调用脚本时反转输入/输出Allocation
顺序 - 它有效并取决于你获取参数和顺序正确。对于RS,它们只是指向要操纵的某种类型的后备数据的对象。由于两者都是使用Allocation.createFromBitmap()
调用创建的,因此只要Bitmap
对象是可变的,它们就可以用作输入或输出。
同样,对输入和输出使用相同的Allocation
是不正常的,但也不是无效的。它只是意味着您的输入正在快速变化。只要您的脚本在为特定Element
调用根函数时没有访问数据中的其他Element
,那么它应该可以正常工作(如您所见)。