DrawBitmapMesh 如何在 Android Canvas 中工作

发布于 2024-10-10 05:59:10 字数 1374 浏览 1 评论 0原文

我想在矩形上绘制位图。我使用以下值:

    this.meshWidth = 1;
    this.meshHeight = 1;
    this.verts = new float[8];
    this.points[0].x = (float)(this.getWidth()/4);
    this.points[0].y = (float)(this.getHeight()/4);
    this.points[1].x = (float)(this.points[0].x+this.getWidth()/2);
    this.points[1].y = (float)(this.points[0].y);
    this.points[2].x = (float)(this.points[0].x);
    this.points[2].y = (float)(this.points[0].y+this.getHeight()/2);
    this.points[3].x = (float)(this.points[1].x);
    this.points[3].y = (float)(this.points[2].y);

点数组是我的顶点数组。

我的 onDraw 方法的

public void onDraw(Canvas canvas){
    //canvas.drawBitmap(bitmap, 20,20, null);
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    canvas.drawLine(this.points[0].x, this.points[0].y, this.points[1].x, this.points[1].y, paint);
    canvas.drawLine(this.points[1].x, this.points[1].y, this.points[3].x, this.points[3].y, paint);
    canvas.drawLine(this.points[3].x, this.points[3].y, this.points[2].x, this.points[2].y, paint);
    canvas.drawLine(this.points[2].x, this.points[2].y, this.points[0].x, this.points[0].y, paint);
    canvas.drawBitmapMesh(this.bitmap, meshWidth, meshHeight, verts, 0, null, 0, null);
}

输出是这样的 alt text

我想在用蓝线包围的矩形上绘制位图..

I want to draw a bitmap on a rectangle. I use the values below:

    this.meshWidth = 1;
    this.meshHeight = 1;
    this.verts = new float[8];
    this.points[0].x = (float)(this.getWidth()/4);
    this.points[0].y = (float)(this.getHeight()/4);
    this.points[1].x = (float)(this.points[0].x+this.getWidth()/2);
    this.points[1].y = (float)(this.points[0].y);
    this.points[2].x = (float)(this.points[0].x);
    this.points[2].y = (float)(this.points[0].y+this.getHeight()/2);
    this.points[3].x = (float)(this.points[1].x);
    this.points[3].y = (float)(this.points[2].y);

points array is my vertex array.

my onDraw method

public void onDraw(Canvas canvas){
    //canvas.drawBitmap(bitmap, 20,20, null);
    Paint paint = new Paint();
    paint.setColor(Color.BLUE);
    canvas.drawLine(this.points[0].x, this.points[0].y, this.points[1].x, this.points[1].y, paint);
    canvas.drawLine(this.points[1].x, this.points[1].y, this.points[3].x, this.points[3].y, paint);
    canvas.drawLine(this.points[3].x, this.points[3].y, this.points[2].x, this.points[2].y, paint);
    canvas.drawLine(this.points[2].x, this.points[2].y, this.points[0].x, this.points[0].y, paint);
    canvas.drawBitmapMesh(this.bitmap, meshWidth, meshHeight, verts, 0, null, 0, null);
}

The output is this
alt text

I want to draw bitmap on rectangle surrounded with blue lines..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

柠檬色的秋千 2024-10-17 05:59:10

了解 DrawBitmapMesh 函数所需的所有内容都可以在 Android 开发人员文档中找到。请参阅Android 开发者文档

不过,我在这里用我自己的话来解释一下。该函数的语法是:

public void drawBitmapMesh (Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)

位图显然是您要使用的位图。现在想象一下位图上的网格,其中 meshWidth+1 点沿着图像的行,meshHeight+1 点沿着位图的列。您可以在 verts 变量中指定这些点或顶点。这些是以行优先格式输入的,这意味着您在 vert 中从左到右输入第 1 行的顶点,然后从左到右输入第 2 行的顶点,依此类推,即如果我们有 4 x 4 个点,那么我们就有一些东西像这样:

*01 *02 *03 *04

*05 *06 *07 *08

*09 *10 *11 *12

*13 *14 *15 *16

其中 *n 是坐标适当放置的顶点(x,y)位图图像上。您可以将 vert 数组定义为:

vert[0] = (*01).x;
vert[1] = (*01).y;
vert[2] = (*02).x;
vert[3] = (*02).y;
...

如果要将这些点均匀分布在位图上,那么理论上,drawBitmapMesh 会提供与 drawBitmap 函数相同的输出。但是,如果您将这些顶点移离其“自然”位置,则 drawBitmapMesh 将开始按照规范拉伸位图。

您可以将剩余的函数参数分别设置为 0、null、0、null,就像您在示例中所做的那样。

Everything you need to understand the DrawBitmapMesh function can be found in the Android developer documentation. See Android developer documentation.

However, I will explain it here in my own words. The syntax for the function is:

public void drawBitmapMesh (Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)

The bitmap is clearly the bitmap you want to use. Now imagine a grid over the bitmap with meshWidth+1 points along the rows of the image and meshHeight+1 points down the columns of the bitmap. You specify these points, or vertices, in the verts variable. These are entered in row-major format, meaning that you enter the vertices in vert from left to right for row 1, then left to right for row 2, and so on, i.e. if we have 4 x 4 points, then we have something like this:

*01 *02 *03 *04

*05 *06 *07 *08

*09 *10 *11 *12

*13 *14 *15 *16

where *n is a vertex (x, y) with coordinates laid appropriately over the bitmap image. You would define your vert array as:

vert[0] = (*01).x;
vert[1] = (*01).y;
vert[2] = (*02).x;
vert[3] = (*02).y;
...

If you were to distribute these points uniformly across the bitmap then the drawBitmapMesh would in theory give the same output as the drawBitmap function. However, if you displace these vertices away from their "natural" position, then the drawBitmapMesh will begin to stretch the bitmap as per specification.

You can set the remaining function arguments to 0, null, 0, null respectively as you have done in your example.

暖风昔人 2024-10-17 05:59:10

如果您所做的只是绘制一个矩形,则根本不需要使用网格。使用网格会更昂贵。

If all you are doing is draw a rectangle, you don't need to use a mesh at all. It will be more expensive to use the mesh.

九命猫 2024-10-17 05:59:10

您没有在上面的代码中初始化顶点。如果您实际为 verts 元素分配值,它应该执行您想要的操作(尽管,正如 Romain 所说,这不是完成任务的最佳方法)。

You're not initializing verts in the code above. It should do what you want if you actually assign values to the verts elements (though, as Romain said, it's not the best way to accomplish the task).

眼泪都笑了 2024-10-17 05:59:10
public class MainActivity extends Activity
{
    private Bitmap bitmap;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this, R.drawable.jinta));
    }
private class MyView extends View
    {
             private final int WIDTH = 20;
        private final int HEIGHT = 20;

        private final int COUNT = (WIDTH + 1) * (HEIGHT + 1);

        private final float[] verts = new float[COUNT * 2];

        private final float[] orig = new float[COUNT * 2];
        public MyView(Context context, int drawableId)
        {
            super(context);
            setFocusable(true);
                    bitmap = BitmapFactory.decodeResource(getResources()
                    , drawableId);
             float bitmapWidth = bitmap.getWidth();
            float bitmapHeight = bitmap.getHeight();
            int index = 0;
            for (int y = 0; y <= HEIGHT; y++)
            {
                float fy = bitmapHeight * y / HEIGHT;
                for (int x = 0; x <= WIDTH; x++)
                {
                    float fx = bitmapWidth * x / WIDTH;

                    orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
                    orig[index * 2 + 1] = verts[index * 2 + 1] = fy;
                    index += 1;
                }
            }

            setBackgroundColor(Color.WHITE);
        }
        @Override
        protected void onDraw(Canvas canvas)
        {
                       canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts
                    , 0, null, 0,null);
        }

        private void warp(float cx, float cy)
        {
            for (int i = 0; i < COUNT * 2; i += 2)
            {
                float dx = cx - orig[i + 0];
                float dy = cy - orig[i + 1];
                float dd = dx * dx + dy * dy;
                     float d = (float) Math.sqrt(dd);

                float pull = 100000 / ((float) (dd * d));

                if (pull >= 1)
                {
                    verts[i + 0] = cx;
                    verts[i + 1] = cy;
                }
                else
                {

                    verts[i + 0] = orig[i + 0] + dx * pull;
                    verts[i + 1] = orig[i + 1] + dy * pull;
                }
            }
                     invalidate();
        }
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
                 warp(event.getX(), event.getY());
            return true;
        }
    }
}
public class MainActivity extends Activity
{
    private Bitmap bitmap;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this, R.drawable.jinta));
    }
private class MyView extends View
    {
             private final int WIDTH = 20;
        private final int HEIGHT = 20;

        private final int COUNT = (WIDTH + 1) * (HEIGHT + 1);

        private final float[] verts = new float[COUNT * 2];

        private final float[] orig = new float[COUNT * 2];
        public MyView(Context context, int drawableId)
        {
            super(context);
            setFocusable(true);
                    bitmap = BitmapFactory.decodeResource(getResources()
                    , drawableId);
             float bitmapWidth = bitmap.getWidth();
            float bitmapHeight = bitmap.getHeight();
            int index = 0;
            for (int y = 0; y <= HEIGHT; y++)
            {
                float fy = bitmapHeight * y / HEIGHT;
                for (int x = 0; x <= WIDTH; x++)
                {
                    float fx = bitmapWidth * x / WIDTH;

                    orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
                    orig[index * 2 + 1] = verts[index * 2 + 1] = fy;
                    index += 1;
                }
            }

            setBackgroundColor(Color.WHITE);
        }
        @Override
        protected void onDraw(Canvas canvas)
        {
                       canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts
                    , 0, null, 0,null);
        }

        private void warp(float cx, float cy)
        {
            for (int i = 0; i < COUNT * 2; i += 2)
            {
                float dx = cx - orig[i + 0];
                float dy = cy - orig[i + 1];
                float dd = dx * dx + dy * dy;
                     float d = (float) Math.sqrt(dd);

                float pull = 100000 / ((float) (dd * d));

                if (pull >= 1)
                {
                    verts[i + 0] = cx;
                    verts[i + 1] = cy;
                }
                else
                {

                    verts[i + 0] = orig[i + 0] + dx * pull;
                    verts[i + 1] = orig[i + 1] + dy * pull;
                }
            }
                     invalidate();
        }
        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
                 warp(event.getX(), event.getY());
            return true;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文