如何find使用Renderscript的2位图之间的区别?

我有两个完全相同大小的位图,我想在两者之间find最小的变化区域。 这是一个Kotlin相当于我正在做的事情:

var minX = Int.MAX_VALUE var minY = Int.MAX_VALUE var maxX = 0 var maxY = 0 for (i in 0 until cols) { for (j in 0 until rows) { if (bitmapOne.getPixel(i, j) != bitmapTwo.getPixel(i, j)) { if (i  maxX) maxX = i if (j  maxY) maxY = j } } } 

我所需要的只是矩形的四个点,它们是最小的变化区域。 根据我做的一些测试,Renderscript位图迭代的速度更快,所以我正在尝试学习Renderscript并移植这个Kotlin代码。

我面临的问题是我无法将2位图分配给任何映射内核。 文件说

“如果您需要比内核更多的输入或输出分配,则应将这些对象绑定到rs_allocation脚本全局variables,并通过rsGetElementAt_type()或rsSetElementAt_type()从内核或可调用函数进行访问。

但是这方面没有足够的例子。

第二个问题是如何得到一个返回types,因为没有一个内核具有返回types – 到目前为止我看到的输入/输出分配示例都是相同的维度。 但我需要一个不同的维度作为输出(只是一个Int4)。

通过减少内核文档,似乎他们也不能一起处理2个分配。

到目前为止,我的理解可能是错误的。 将不胜感激任何帮助,可以让我开始。

脚本全局将绝对有助于解决您的情况。 从本质上讲,它们是Java / Kotlin端可以访问的脚本variables。 如果您只能使用Android 7+,则可以将其作为缩减内核(而不是映射内核)来执行此操作。 基本上没有“输出”分配。

下面是通过映射内核做一个简单的写法。 我没有试过或编译过,所以你可能需要调整它。 假设你有两个Bitmap对象,它们是相同的大小/格式(在这里没有error handling来保持简短),并且在一个Activity中工作,你可以像这样设置它:

 // You should only create the Rendescript context and script one // time in the lifetime of your Activity. It is an expensive op. Renderscript rs = Renderscript.create(this); ScriptC_diffBitmap script = new ScriptC_diffBitmap(rs); Allocation inAlloc1 = Allocation.createFromBitmap(rs, bitmap1, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); Allocation inAlloc2 = Allocation.createFromBitmap(rs, bitmap2, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); Allocation outAlloc = Allocation.createTyped(rs, inAlloc2.getType()); script.set_maxX(0); script.set_maxY(0); script.set_minX(Int.MAX_VALUE); script.set_minY(Int.MAX_VALUE); script.set_inBitmap1(inAlloc1); script.foreach_root(inAlloc2, outAlloc); // Get back the min/max values and do whatever you need minX = script.get_minX(); minY = script.get_minY(); maxX = script.get_maxX(); maxY = script.get_mayY(); 

Rendescript代码支持这个(再次使用映射内核 ),名为diffBitmap.rs

 #pragma version(1) #pragma rs java_package_name(com.example.DiffBitmap) int32_t minX; int32_t minY; int32_t maxX; int32_t maxY; rs_allocation inBitmap1; uchar4 RS_KERNEL root(uchar4 inBitmap2Point, uint32_t x, uint32_t y) { uchar4 inBitmap1Point = rsGetElementAt_uchar4(inBitmap1, x, y); if ((inBitmap1Point.r != inBitmap2Point.r) || (inBitmap1Point.g != inBitmap2Point.g) || (inBitmap1Point.b != inBitmap2Point.b) || (inBitmap1Point.a != inBitmap2Point.a)) { if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; } // Since we have to return an output, just return bitmap1 return inBitmap1Point; }