如何将位图绘制到另一个,但进入给定的四边形(不必是矩形)?

时间:2015-08-24 10:53:16

标签: android bitmap android-canvas tilt

假设我有2个位图。一个是smallBitmap,一个是largeBitmap。

我想将整个smallBitmap绘制到largeBitmap中,但只绘制到largeBitmap的一部分,而不是直接调整,而是改为quadrilateral

我认为草图最能描述我的意思:

enter image description here

此方案的一个示例是倾斜的智能手机图像(如thisthis),您需要将屏幕截图放入其屏幕。

输入是:smallBitmap,largeBitmap,largeBitmap的“四边形”坐标(放置smallBitmap的位置)。

largeBitmap的“四边形”只有4个坐标,不一定是矩形。例如,它可以是平行四边形或梯形。

我需要将smallBitmap缩放到largeBitmap中的四边形,并且还支持中心裁剪缩放,这样它就不会失真

我还需要知道如何以同样的方式处理文本,但我想这是关于相同的解决方案。

这是我尝试过的东西,但它甚至没有扩展:

    //mBigBitmap: size is 720x1280
    //mSmallBitmap: size is 720x720
    mLeftTop = new Point(370, 358);
    mRightTop = new Point(650, 384);
    mLeftBot = new Point(375, 972);
    mRightBot = new Point(660, 942);
    Canvas canvas = new Canvas(mBigBitmap);
    final Matrix matrix = new Matrix();
    matrix.setPolyToPoly(new float[]{0, 0,
                    mBigBitmap.getWidth() - 1, 0,
                    0, mBigBitmap.getHeight() - 1,
                    mBigBitmap.getWidth() - 1, mBigBitmap.getHeight() - 1},
            0,
            new float[]{mLeftTop.x, mLeftTop.y,
                    mRightTop.x, mRightTop.y,
                    mLeftBot.x, mLeftBot.y,
                    mRightBot.x, mRightBot.y
            }
            , 0, 4);
    canvas.drawBitmap(mSmallBitmap, matrix, new Paint());

2 个答案:

答案 0 :(得分:0)

倾斜位图,可能Matrix很方便。

   /*use values accordingly*/
   Matrix matrix = new Matrix();
   matrix.postScale(curScale, curScale);  
   matrix.postRotate(curRotate);
   matrix.postSkew(curSkewX, curSkewY);

   Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bmpWidth, bmpHeight, matrix, true);
   myImageView.setImageBitmap(resizedBitmap);

答案 1 :(得分:0)

对于我的回答,我将较小的Bitmap绘制为较大的Bitmap,然后将其绘制到SurfaceView

  1. 使用边界四边形创建边界矩形。
  2. 使用边界矩形创建转换Matrix
  3. 使用Matrix.ScaleToFit.CENTER将边界矩形填充为较小Bitmap的最大尺寸。
  4. 完成这些步骤后,只需绘制更大的Bitmap正在使用的画布。边界四边形绘制为红色,边界矩形为蓝色,大Bitmap绘制为绿色。将较小的Bitmap替换为蓝色Bitmap(边界矩形)。

    public class MainActivity extends Activity {
    final String TAG = this.getClass().getName();
    
    SurfaceView surfaceView;
    Bitmap bitmap;
    Bitmap bigBitmap;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback2() {
            @Override
            public void surfaceRedrawNeeded(SurfaceHolder holder) {
    
            }
    
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Canvas surfaceCanvas = holder.lockCanvas();
    
                surfaceCanvas.drawBitmap(bigBitmap, 0, 0, new Paint());
    
                holder.unlockCanvasAndPost(surfaceCanvas);
            }
    
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
            }
    
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
    
            }
        });
    
        bitmap = Bitmap.createBitmap(64, 192, Bitmap.Config.ARGB_8888);
        {
            Canvas canvas = new Canvas(bitmap);
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            canvas.drawRect(0, 0, 64, 192, paint);
        }
    
        bigBitmap = Bitmap.createBitmap(768,768, Bitmap.Config.ARGB_8888);
        {
            Canvas canvas = new Canvas(bigBitmap);
    
            // Fill background - For visual reference
            Paint paint = new Paint();
            paint.setColor(Color.GREEN);
            canvas.drawRect(0, 0, bigBitmap.getWidth(), bigBitmap.getHeight(), paint);
    
            // Setup transformation
            Matrix matrixPoly = new Matrix();
            Log.i(TAG, "matrixPoly: " + matrixPoly);
    
            // Draw Quadrilateral - For visual reference
            boolean canScale;
            canScale = matrixPoly.setPolyToPoly(new float[]{0,0, 64,0, 0,192, 64,192},
                    0,
                    new float[]{32,32, 96,16, 16,300, 128,256},
                    0,
                    4);
    
            Log.i(TAG, "matrixPoly: " + matrixPoly);
            Log.i(TAG, "matrixPoly canScale: " + canScale);
    
            canvas.drawBitmap(bitmap, matrixPoly, new Paint());
    
            // Points of Quadrilateral
            // {32,32, 96,16, 16,300, 128,256}
            float rectInQLeft = Math.max(32, 16);
            float rectInQTop = Math.min(32, 16);
            float rectInQRight = Math.min(96, 128);
            float rectInQBottom = Math.max(300, 256);
            ;
            Matrix matrixRect = new Matrix();
            Log.i(TAG, "matrixRect: " + matrixRect);
            canScale = matrixRect.setRectToRect(new RectF(0, 0, 64, 192),
                    new RectF(rectInQLeft, rectInQTop, rectInQRight, rectInQBottom),
                    Matrix.ScaleToFit.CENTER);
    
            Log.i(TAG, "matrixRect: " + matrixRect);
            Log.i(TAG, "matrixRect canScale: " + canScale);
    
            // Draw scaled bitmap
            Canvas smallBitmapCanvas = new Canvas(bitmap);
            Paint smallBitmapPaint = new Paint();
            smallBitmapPaint.setColor(Color.BLUE);
            smallBitmapCanvas.drawRect(0, 0, 64, 192, smallBitmapPaint);
    
            canvas.drawBitmap(bitmap, matrixRect, new Paint());
        }
    }