在某些情况下,将图像扭曲成四边形在Android上是失败的

在某些情况下,将图像扭曲成四边形在Android上是失败的,android,matrix,android-bitmap,perspective,Android,Matrix,Android Bitmap,Perspective,我正在使用matrix.setPolyToPoly函数将位图的选定区域(4个角)转换为矩形,通常情况下,它的效果非常好。但在下一个例子中: Polytoply函数无法进行透视变换: 我已经画了两条线进行测试,这些线标记了我想要的四个选定点的位置 我做错了什么?谢谢 编辑:我已经用canvas.drawBitmapMesh解决了这个问题,谢谢你的建议 这是最后的代码 private float[] generateVertices(int widthBitmap, int heightBitm

我正在使用matrix.setPolyToPoly函数将位图的选定区域(4个角)转换为矩形,通常情况下,它的效果非常好。但在下一个例子中:

Polytoply函数无法进行透视变换:

我已经画了两条线进行测试,这些线标记了我想要的四个选定点的位置

我做错了什么?谢谢

编辑:我已经用canvas.drawBitmapMesh解决了这个问题,谢谢你的建议

这是最后的代码

private float[] generateVertices(int widthBitmap, int heightBitmap) {
    float[] vertices=new float[(WIDTH_BLOCK+1)*(HEIGHT_BLOCK+1)*2];

    float widthBlock = (float)widthBitmap/WIDTH_BLOCK;
    float heightBlock = (float)heightBitmap/HEIGHT_BLOCK;

    for(int i=0;i<=HEIGHT_BLOCK;i++)
        for(int j=0;j<=WIDTH_BLOCK;j++) {
            vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)] = j * widthBlock;
            vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)+1] = i * heightBlock;
        }
    return vertices;
}

private Bitmap perspectiveTransformation(Bitmap bitmap, ArrayList<Point> bitmapPoints) {

    Bitmap correctedBitmap;
    int maxX = (int) Math.max(Math.abs(bitmapPoints.get(0).x - bitmapPoints.get(1).x), Math.abs(bitmapPoints.get(2).x - bitmapPoints.get(3).x));
    int maxY = (int) Math.max(Math.abs(bitmapPoints.get(0).y - bitmapPoints.get(3).y), Math.abs(bitmapPoints.get(1).y - bitmapPoints.get(2).y));
    Log.d("max", "x=" + maxX + " y=" + maxY); //This is the desired final size

    Bitmap.Config conf = Bitmap.Config.ARGB_8888;
    correctedBitmap = Bitmap.createBitmap(maxX,maxY,conf); //the final bitmap
    float mVertices[] =generateVertices(bitmap.getWidth(),bitmap.getHeight());

    Point mLeftTop = bitmapPoints.get(0);
    Point mRightTop = bitmapPoints.get(1);
    Point mLeftBot = bitmapPoints.get(3);
    Point mRightBot = bitmapPoints.get(2);  //the points on the image where the user has clicked

    Canvas canvas = new Canvas(correctedBitmap);

    Matrix matrix = new Matrix();
    matrix.setPolyToPoly(
            new float[]{mLeftTop.x, mLeftTop.y,
                    mRightTop.x, mRightTop.y,
                    mRightBot.x, mRightBot.y,
                    mLeftBot.x, mLeftBot.y   //the user's points
            },
            0,
            new float[]{0, 0,
                    maxX - 1, 0,
                    maxX - 1, maxY - 1,
                    0, maxY - 1             //where I want the user points in the corrected image
            }
            , 0, 4);

    canvas.concat(matrix);

    Paint paint = new Paint();
    paint.setAntiAlias(true);       //testing parameters
    paint.setFilterBitmap(true);    //testing parameters

    paint.setColor(Color.BLUE);
    paint.setStyle(Paint.Style.STROKE);

    canvas.drawBitmapMesh(bitmap, WIDTH_BLOCK , HEIGHT_BLOCK, mVertices,0,null,0, paint);  //draw the original bitmap into the corrected bitmap with PolyToPoly transformation matrix

    canvas.drawLine(mLeftTop.x, mLeftTop.y, mRightBot.x, mRightBot.y, paint); //draw two lines for testing the transformation matrix
    canvas.drawLine(mLeftBot.x, mLeftBot.y, mRightTop.x, mRightTop.y, paint);

    //bitmap.recycle();  //just testing

    return correctedBitmap;
}
private float[]generateVertices(int-widthBitmap,int-heightBitmap){
浮动[]顶点=新浮动[(宽度块+1)*(高度块+1)*2];
浮动宽度块=(浮动)宽度位图/宽度块;
浮动高度块=(浮动)高度位图/高度块;
对于(int i=0;i
private float[]generateVertices)(int-widthBitmap,int-heightBitmap){
浮动[]顶点=新浮动[(宽度块+1)*(高度块+1)*2];
浮动宽度块=(浮动)宽度位图/宽度块;
浮动高度块=(浮动)高度位图/高度块;

for(int i=0;i与drawBitmap有相同的问题。在Skia-Android的画布后端打开了一个问题


你不能用
setpolytoply
做任何事情,试试
Canvas.drawBitmapMesh
代替谢谢!我已经用最后的代码更新了问题。@Pepantacruz感谢你提出了一个清晰、表达得很好的问题。所以的精神是,问题和答案可能在原始帖子发布很久之后对其他人有帮助。这是精神吗,cou您是否可以将编辑还原为您的问题,以便代码为原始帖子的代码(答案中的工作代码与您所做的相同)?此外,您是否可以“接受”您的答案。通过这样做,未来的访问者将能够看到出现问题的代码与解决问题的代码之间的明显区别。“接受”将明显表明此答案解决了问题。我正在尝试解决类似的问题!!您能解释一下您的意思吗通过本例中的“宽度块”和“高度块”?这是网格每个块的所需大小。例如:图像大小=(1000px,500px),您可以将宽度块和高度块分别定义为100和50,或者200和100,或者50和100,或者……您知道;).谢谢你的回答和问题-送了一份赏金说谢谢谢谢你!!@Fattie
private float[] generateVertices(int widthBitmap, int heightBitmap) {
    float[] vertices=new float[(WIDTH_BLOCK+1)*(HEIGHT_BLOCK+1)*2];

    float widthBlock = (float)widthBitmap/WIDTH_BLOCK;
    float heightBlock = (float)heightBitmap/HEIGHT_BLOCK;

    for(int i=0;i<=HEIGHT_BLOCK;i++)
        for(int j=0;j<=WIDTH_BLOCK;j++) {
            vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)] = j * widthBlock;
            vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)+1] = i * heightBlock;
        }
    return vertices;
}

private Bitmap perspectiveTransformation(Bitmap bitmap, ArrayList<Point> bitmapPoints) {

    Bitmap correctedBitmap;
    int maxX = (int) Math.max(Math.abs(bitmapPoints.get(0).x - bitmapPoints.get(1).x), Math.abs(bitmapPoints.get(2).x - bitmapPoints.get(3).x));
    int maxY = (int) Math.max(Math.abs(bitmapPoints.get(0).y - bitmapPoints.get(3).y), Math.abs(bitmapPoints.get(1).y - bitmapPoints.get(2).y));
    Log.d("max", "x=" + maxX + " y=" + maxY); //This is the desired final size

    Bitmap.Config conf = Bitmap.Config.ARGB_8888;
    correctedBitmap = Bitmap.createBitmap(maxX,maxY,conf); //the final bitmap
    float mVertices[] =generateVertices(bitmap.getWidth(),bitmap.getHeight());

    Point mLeftTop = bitmapPoints.get(0);
    Point mRightTop = bitmapPoints.get(1);
    Point mLeftBot = bitmapPoints.get(3);
    Point mRightBot = bitmapPoints.get(2);  //the points on the image where the user has clicked

    Canvas canvas = new Canvas(correctedBitmap);

    Matrix matrix = new Matrix();
    matrix.setPolyToPoly(
            new float[]{mLeftTop.x, mLeftTop.y,
                    mRightTop.x, mRightTop.y,
                    mRightBot.x, mRightBot.y,
                    mLeftBot.x, mLeftBot.y   //the user's points
            },
            0,
            new float[]{0, 0,
                    maxX - 1, 0,
                    maxX - 1, maxY - 1,
                    0, maxY - 1             //where I want the user points in the corrected image
            }
            , 0, 4);

    canvas.concat(matrix);

    Paint paint = new Paint();
    paint.setAntiAlias(true);       //testing parameters
    paint.setFilterBitmap(true);    //testing parameters

    paint.setColor(Color.BLUE);
    paint.setStyle(Paint.Style.STROKE);

    canvas.drawBitmapMesh(bitmap, WIDTH_BLOCK , HEIGHT_BLOCK, mVertices,0,null,0, paint);  //draw the original bitmap into the corrected bitmap with PolyToPoly transformation matrix

    canvas.drawLine(mLeftTop.x, mLeftTop.y, mRightBot.x, mRightBot.y, paint); //draw two lines for testing the transformation matrix
    canvas.drawLine(mLeftBot.x, mLeftBot.y, mRightTop.x, mRightTop.y, paint);

    //bitmap.recycle();  //just testing

    return correctedBitmap;
}