如何将位图绘制到另一个,但绘制到给定的四边形(不一定是矩形)中? [英] How to draw a bitmap to another, but into a given quadrilateral (not necessary a rectangle)?

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

问题描述

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

我想将整个smallBitmap绘制成largeBitmap,但只绘制到largeBitmap的一部分,而不是在一个直线regtangle中,而是绘制成一个

这种情况的一个例子是倾斜的智能手机图像(如 thisthis),您需要将屏幕截图放入其屏幕.

输入为:smallBitmap、largeBitmap、largeBitmap的四边形"坐标(smallBitmap放在哪里).

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

我需要将smallBitmap缩放到largeBitmap内的四边形,并且还支持center-crop缩放,这样它就不会变形

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

<小时>

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

//mBigBitmap:大小为720x1280//mSmallBitmap:大小为720x720mLeftTop = 新点(370, 358);mRightTop = 新点 (650, 384);mLeftBot = 新点(375, 972);mRightBot = 新点 (660, 942);Canvas canvas = new Canvas(mBigBitmap);最终矩阵矩阵 = 新矩阵();matrix.setPolyToPoly(new float[]{0, 0,mBigBitmap.getWidth() - 1, 0,0, mBigBitmap.getHeight() - 1,mBigBitmap.getWidth() - 1, mBigBitmap.getHeight() - 1},0,新的浮点[]{mLeftTop.x, mLeftTop.y,mRightTop.x, mRightTop.y,mLeftBot.x, mLeftBot.y,mRightBot.x, mRightBot.y}, 0, 4);canvas.drawBitmap(mSmallBitmap, matrix, new Paint());

解决方案

根据这篇文章找到了答案>.

似乎无法使用 Matrix,因为它无法创建可出现在 3d 世界中的梯形形状.

所以建议使用Camera" 类,例如:

 Canvas canvas = new Canvas(bigBitmap);矩阵矩阵 = 新矩阵();相机相机 = 新相机();相机.save();相机.translate(...,...,0);camera.rotateX(...);camera.rotateY(...);camera.rotateZ(...);相机.getMatrix(矩阵);int centerX = bigBitmap.getWidth()/2;int centerY = bigBitmap.getHeight()/2;matrix.preTranslate(-centerX, -centerY);//这是获得正确视角的关键矩阵.postTranslate(centerX, centerY);canvas.concat(矩阵);相机.恢复();canvas.drawBitmap(mSmallBitmap, matrix, new Paint());

遗憾的是,如您所见,没有使用坐标,因此您需要使用数字直到正确为止,或者找到一个公式来在坐标和所需值之间进行转换.

我不会将此答案标记为正确答案,因为它不完全符合原始问题的要求(未使用坐标).

另外,在使用此解决方案时,我找不到如何处理文本.

但是,它确实有效,因此可能对其他人有用.

<小时>

似乎 setPolyToPoly 根本不缩放图像的原因是第一个输入数组不正确:它被设置为大位图的大小,而不是小位图的大小.

所以,这是正确的代码:

mLeftTop = new Point(370, 358);mRightTop = 新点 (650, 384);mLeftBot = 新点(375, 972);mRightBot = 新点 (660, 942);Canvas canvas = new Canvas(mBigBitmap);最终矩阵矩阵 = 新矩阵();matrix.setPolyToPoly(new float[]{0, 0,mSmallBitmap.getWidth() - 1, 0,0, mSmallBitmap.getHeight() - 1,mSmallBitmap.getWidth() - 1, mSmallBitmap.getHeight() - 1},0,新的浮点[]{mLeftTop.x, mLeftTop.y,mRightTop.x, mRightTop.y,mLeftBot.x, mLeftBot.y,mRightBot.x, mRightBot.y}, 0, 4);canvas.concat(矩阵);最终油漆油漆 = 新油漆();Paint.setAntiAlias(true);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天全站免登陆