1

我有 2 个大小完全相同的位图,我想找到两者之间变化的最小区域。这是我正在做的 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 < minX) minX = i
            if (i > maxX) maxX = i
            if (j < minY) minY = j
            if (j > maxY) maxY = j
        }
    }
}

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

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

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

但是这方面的例子还不够多。

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

在浏览reduce内核文档时,他们似乎也不能一起处理2个分配。

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

4

1 回答 1

2

脚本全局变量肯定会帮助您解决问题。本质上,它们是 Java/Kotlin 端可以访问以设置或获取的脚本变量。如果您只能使用 Android 7+,则可以将其作为缩减内核(而不是映射内核)来执行。基本上,没有“输出”分配。

这是通过映射内核执行此操作的快速记录。我没有尝试或编译过这个,所以你可能需要调整它。假设您有两个Bitmap对象并且它们的大小/格式相同(此处没有错误处理以保持简短),并且正在工作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;
}
于 2018-01-09T11:48:12.550 回答