开发者

How drawBitmapMesh works in android canvas

开发者 https://www.devze.com 2023-02-02 10:27 出处:网络
I w开发者_开发百科ant to draw a bitmap on a rectangle. I use the values below: this.meshWidth = 1;

I w开发者_开发百科ant 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

How drawBitmapMesh works in android canvas

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


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.


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.


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).


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

精彩评论

暂无评论...
验证码 换一张
取 消