【问题标题】:How drawBitmapMesh works in android canvasdrawBitmapMesh 在 android 画布中的工作原理
【发布时间】:2018-12-30 13:57:33
【问题描述】:

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

    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 数组是我的顶点数组。

我的 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);
}

输出是这个

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

【问题讨论】:

标签: android canvas


【解决方案1】:

您需要了解 DrawBitmapMesh 函数的所有内容都可以在 Android 开发人员文档中找到。见Android developer documentation

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

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

位图显然是您要使用的位图。现在想象一下位图上的网格,meshWidth+1 点沿图像的行,meshHeight+1 指向位图的列。您可以在 verts 变量中指定这些点或顶点。这些以行优先格式输入,这意味着您在第 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,就像您在示例中所做的那样。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 我知道,但我想了解该方法背后的逻辑。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:
      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;
              }
          }
      }
      

      【讨论】:

      • 此代码无效,请分享您的完整代码
      猜你喜欢
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 2021-09-07
      • 2013-04-22
      • 1970-01-01
      相关资源
      最近更新 更多