Renderscript allocation from bitmap

时间:2015-09-01 22:25:54

标签: android renderscript

I'm trying to get into render script and was confused regarding allocations usage. Almost all examples show next algorithm:

  1. Create In and Out Bitmap
  2. Create In and Out Allocation from Bitmaps In and Out correspondingly
  3. Configure script and perform forEach method
  4. copy result from Out allocation into bitmap using copyTo method

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?

1 个答案:

答案 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,那么它应该可以正常工作(如您所见)。