如何绘制一个位图到另一个,而是进入一个给定的四边形(没有必要矩形)? [英] How to draw a bitmap to another, but into a given quadrilateral (not necessary a rectangle)?

查看:294
本文介绍了如何绘制一个位图到另一个,而是进入一个给定的四边形(没有必要矩形)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

欲绘制整个smallBitmap成largeBitmap,但只largeBitmap的一部分,而不是在一条直线regtangle,但成 四边形 代替。

我觉得一个草图最能描述一下我的意思是:

输入图像的描述在这里

这种情况的一个例子是一个倾斜的智能手机的图像(如的 或<一href="https://cdn2.vox-cdn.com/thumbor/mPWCe0qOA1GRjJpFe8RojqCBPp4=/cdn0.vox-cdn.com/uploads/chorus_asset/file/3456662/galaxys6-9.0.png"相对=nofollow> ),你需要把截图到它的屏幕。

输入为:smallBitmap,largeBitmap的largeBitmap的四边形坐标(在哪里放置smallBitmap)

在四边形的largeBitmap仅仅有4个坐标,这是没有必要的矩形。这可能是一个平行四边形或梯形,例如

我需要缩放smallBitmap入largeBitmap内的四边形,并且还支持中心作物缩放,以便它不会扭曲

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


下面的东西,我试过,但它甚至没有规模:

  // mBigBitmap:尺寸为720x1280
    // mSmallBitmap:大小为720x720
    mLeftTop =新的点(370,358);
    mRightTop =新的点(650,384);
    mLeftBot =新的点(375,972);
    mRightBot =新的点(660,942);
    帆布油画=新的Canvas(mBigBitmap);
    最终矩阵的矩阵=新的Matrix();
    matrix.setPolyToPoly(新浮法[] {0,0,
                    mBigBitmap.getWidth() -  1,0,
                    0,mBigBitmap.getHeight() -  1,
                    mBigBitmap.getWidth() -  1,mBigBitmap.getHeight() -  1},
            0,
            新浮法[] {m​​LeftTop.x,mLeftTop.y,
                    mRightTop.x,mRightTop.y,
                    mLeftBot.x,mLeftBot.y,
                    mRightBot.x,mRightBot.y
            }
            ,0,4);
    canvas.drawBitmap(mSmallBitmap,矩阵,新的油漆());
 

解决方案

找到基于 这个帖子答案

似乎矩阵不能使用,因为它不能形成一个能发生在一个三维世界梯形形状。

那么,什么是建议有使用 摄像机 级,因为这样:

 画布油画=新的Canvas(bigBitmap);
    字模=新的Matrix();
    摄像头摄像头=新相机();
    camera.save();
    camera.translate(...,...,0);
    camera.rotateX(...);
    camera.rotateY(...);
    camera.rotateZ(...);
    camera.getMatrix(矩阵);
    INT的centerX = bigBitmap.getWidth()/ 2;
    INT centerY = bigBitmap.getHeight()/ 2;
    。矩阵preTranslate(-centerX,-centerY); //这是关键,以获得正确的观看视角
    matrix.postTranslate(的centerX,centerY);
    canvas.concat(矩阵);
    camera.restore();
    canvas.drawBitmap(mSmallBitmap,矩阵,新的油漆());
 

可悲的是,正如你看到的,坐标是不被使用,所以你需要或者与数字打,直到你得到它的权利,或者寻找一个公式的坐标和所需要的价值观之间进行转换。

我不会庆祝这个答案是正确的,因为它不完全符合的原来问题的规定(没有坐标正在使用)。

另外,我怎么也找不到,而使用此解决方案来处理文本。

不过,它的工作,所以它可能是为别人有用。


编辑:似乎对于setPolyToPoly到不是在所有缩放图像的原因是,第一输入阵列是不正确的:它被设置,而不是小一个作为大的位图的大小,

所以,这是正确的code:

  mLeftTop =新的点(370,358);
mRightTop =新的点(650,384);
mLeftBot =新的点(375,972);
mRightBot =新的点(660,942);
帆布油画=新的Canvas(mBigBitmap);
最终矩阵的矩阵=新的Matrix();
matrix.setPolyToPoly(新浮法[] {0,0,
                mSmallBitmap.getWidth() -  1,0,
                0,mSmallBitmap.getHeight() -  1,
                mSmallBitmap.getWidth() -  1,mSmallBitmap.getHeight() -  1},
        0,
        新浮法[] {m​​LeftTop.x,mLeftTop.y,
                mRightTop.x,mRightTop.y,
                mLeftBot.x,mLeftBot.y,
                mRightBot.x,mRightBot.y
        }
        ,0,4);
canvas.concat(矩阵);
最终的涂料粉刷=新的油漆();
paint.setAntiAlias​​(真正的);
canvas.drawBitmap(mSmallBitmap,0,0,油漆);
 

然而,对于中心裁剪,它还是有这个问题,但如果你知道矩形的正确尺寸也得到了倾斜之前,可以在做裁剪,并设置其为输入。

对于文本,这是可能的和往常一样,作为画布保持与所创建的矩阵。

Suppose I have 2 bitmaps. One is smallBitmap, and one is largeBitmap.

I want to draw the entire smallBitmap into largeBitmap, but only to a part of largeBitmap, and not in a straight regtangle, but into a quadrilateral instead.

I think a sketch will best describe what I mean:

An example of this scenario is a tilted smartphone image (like this or this), that you need to put a screenshot into its screen.

The input is: smallBitmap, largeBitmap, "quadrilateral" coordinates of the largeBitmap (where to put the smallBitmap).

The "quadrilateral" of the largeBitmap just has 4 coordinates and it's not necessary a rectangle. It could be a parallelogram or trapezoid, for example.

I need to scale the smallBitmap into the quadrilateral within the largeBitmap, and also support center-crop scaling, so that it won't get distorted

I also need to know how to treat texts the same way, but I guess it's about the same solution.


Here's something that I've tried, but it doesn't even scale:

    //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());

解决方案

Found an answer based on this post.

It seems that Matrix cannot be used as it can't create Trapezoid shapes which can occur in a 3d world.

So what is suggested there is to use the "Camera" class, as such:

    Canvas canvas = new Canvas(bigBitmap);
    Matrix matrix = new Matrix();
    Camera camera = new Camera();
    camera.save();
    camera.translate(...,...,0);
    camera.rotateX(...);
    camera.rotateY(...);
    camera.rotateZ(...);
    camera.getMatrix(matrix);
    int centerX = bigBitmap.getWidth() / 2;
    int centerY = bigBitmap.getHeight() / 2;
    matrix.preTranslate(-centerX, -centerY); //This is the key to getting the correct viewing perspective
    matrix.postTranslate(centerX, centerY);
    canvas.concat(matrix);
    camera.restore();
    canvas.drawBitmap(mSmallBitmap, matrix, new Paint());

Sadly, as you see, the coordinates aren't being used, so you need to either play with the numbers till you get it right, or find a formula to convert between the coordinates and the needed values.

I won't mark this answer as the correct one, because it doesn't fully fit the requirements of the original question (no coordinates are being used).

Plus I can't find how to deal with text while using this solution.

However, it does work, so it might be useful for others.


EDIT: It appears that the reason for setPolyToPoly to not scale the image at all, is that the first input array was incorrect: It was set as the size of the large bitmap, instead of the small one.

So, this is the correct code:

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,
                mSmallBitmap.getWidth() - 1, 0,
                0, mSmallBitmap.getHeight() - 1,
                mSmallBitmap.getWidth() - 1, mSmallBitmap.getHeight() - 1},
        0,
        new float[]{mLeftTop.x, mLeftTop.y,
                mRightTop.x, mRightTop.y,
                mLeftBot.x, mLeftBot.y,
                mRightBot.x, mRightBot.y
        }
        , 0, 4);
canvas.concat(matrix);
final Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawBitmap(mSmallBitmap, 0, 0, paint);

However, for center-cropping, it still has this issue, but if you know the correct size of the rectangle before it got tilted, you can do the cropping before, and set it as the input.

As for the text, this is possible as usual, as the canvas stays with the matrix that was created.

这篇关于如何绘制一个位图到另一个,而是进入一个给定的四边形(没有必要矩形)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆