使用 Android Canvas.drawBitmapMesh 给出意想不到的位图转换

Using Android Canvas.drawBitmapMesh gives unexpected bitmap transformation

使用 Canvas.drawBitmapMesh(),我可以更改图像以模拟透视变化,但图像的更改方式出乎意料。

原始图像 > 变换图像

>>>>> One By One Transform>>>>

canvas.drawBitmapMesh(myBitmap, 1, 1, fourPoints, 0, null, 0, null);

int[] fourPoints 匹配 myBitmap 的尺寸,只是左上角向右移动,右上角向左移动。

POINT: 768.0, 0.0
POINT: 2304.0, 0.0
POINT: 0.0, 2304.0
POINT: 3072.0, 2304.0

请注意右上方的图像有一个意外的对角线 'fold'。这与我在下面生成的图像相反(未使用 Android Canvas drawBitmapMesh)。

预期转换:

我将上述预期结果称为'smooth lines'转换。

增加网格

我尝试将转换的定义网格增加到 2×2 大小。它掩盖了问题,但 'folds' 的问题仍然存在。

二乘二网格

canvas.drawBitmapMesh(myBitmap, 2, 2, ninePoints, 0, null, 0, null);

int[] ninePoints 匹配底部 myBitmap 的尺寸,但调整其余部分以创建梯形。

POINT: 768.0, 0.0
POINT: 1536.0, 0.0
POINT: 2304.0, 0.0
POINT: 384.0, 1152.0
POINT: 1536.0, 1152.0
POINT: 2688.0, 1152.0
POINT: 0.0, 2304.0
POINT: 1536.0, 2304.0
POINT: 3072.0, 2304.0

从编码的角度来看,不断增加网格的大小直到它接近 'smooth lines' 结果是没有问题的,但这似乎会浪费 CPU 处理。也许有一个 技巧 可以让此函数执行我期望的操作,而不是使用 'fold' 对角线?所以我想知道是否有一种方法可以得到一个一个的网格并获得 'smooth lines' 这可能更有效。

你必须为此使用透视矩阵。

初始化一个矩阵,将源点转换为目标点(应为 4 个点):

Matrix m = new Matrix();
m.setPolyToPoly(srcPoints,0,dstPoints,0,4)

其中源点和目标点是浮点数组,表示为 {x1,y1,x2,y2,x3,y3,x4,y4}

然后用

画画
canvas.drawBitmapMesh(myBitmap, m, null);

null 可以替换为可以定义为使用抗锯齿过滤器的 Paint 对象。