2016-03-30 13 views
7

matrix.setPolyToPoly関数を使用して、ビットマップの選択された領域(四隅)を矩形に変換します。しかし、次の例では:画像を四角形に変形することができない場合があります。

4 corners selection image

polyToPoly機能は、視点変換失敗:

Bad transformation image

私はテストのための2つのラインを描いた、私が選択した4つのポイントを配置したい場所を、行がマークします。

私は間違っていますか?ありがとう!

EDIT:私はcanvas.drawBitmapMeshを使用して問題を解決しました。ありがとうございました。pskinkあなたのアドバイスのために!

これは、おかげであなたがsetPolyToPoly` `ですべてを行うことはできません最終的なコード

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; 
} 
+1

、代わりに – pskink

+0

Canvas.drawBitmapMesh''てみました!私は最後のコードで質問を更新しました。 –

+0

@PepSantacruz明確で、よく表現されている質問をありがとう。 SOの精神は、質問と回答が元の投稿の後ずっと他の人に役立つかもしれないということです。この精神は、あなたの質問に編集を元に戻すことができますか?コードは元の投稿のものです(あなたが行ったように答えの作業コードを使って)?また、あなたはあなたの答えを「受け入れる」ことができますか?これらのことを行うことで、将来のビジターは、問題を抱えたコードと問題を解決したコードとの間に明確な違いがあることがわかります。 「受諾」は、この回答が問題を解決したことを明示します。 – Gary99

答えて

1
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; 
} 
+0

偉大な答えと質問に感謝 - 感謝の言葉を贈りました – Fattie

+0

ありがとうございました! @Fattie –

関連する問題