使用Android Canvas.drawBitmapMesh提供意外的位图转换

时间:2018-12-06 22:08:05

标签: android image-processing bitmap android-canvas android-bitmap

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

原始图像>转换后的图像

Original Image >>>>>一对一变换>>>> One by One Mesh

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

请注意,右上方的图像具有意外的对角线“折叠”。这与我下面生成的图像相反(不使用Android Canvas drawBitmapMesh)。

预期的转化:

Expected "Smooth Lines" Transformation (done outside of Android)

我将上述预期结果称为“平滑线” 转换。

增加网格

我尝试将用于转换的定义的网格增加到2乘2的大小。它掩盖了问题,但“褶皱”问题仍然存在。

二乘二网格

Using a two by two mesh

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

从编码的角度来看,不断增加网格的大小直到接近“平滑线条”结果都没有问题,但这似乎会浪费CPU处理。也许有一个 trick 可以使此功能执行我期望的操作,而不是使用对角的“折叠”线?因此,我想知道是否有一种方法可以建立一个一对一的网格并获得可能更有效的“平滑线”。

1 个答案:

答案 0 :(得分:1)

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

初始化一个将源点转换为目的点(应为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对象替换。