关于图形:Android:如何叠加位图并在位图上绘制?

Android: How to overlay a bitmap and draw over a bitmap?

我实际上有三个问题:

  • 在位图上绘制图像或将位图创建为资源然后在位图上绘制它是否更好? 性能明智,哪个更好?
  • 如果我想在位图上绘制透明的东西,该怎么做?
  • 如果要在一个透明位图上覆盖另一个透明位图,我该怎么做?
  • 抱歉,名单很长,但是为了学习,我想探索这两种方法。


    我不敢相信还没有人回答!如此罕见的发生!

    1个

    这个问题对我来说不太有意义。但我给它一个刺。
    如果您要直接绘制到画布(多边形,阴影,文本等),而不是加载位图并将其拖到画布上,这取决于您的绘图的复杂性。
    随着图纸变得越来越复杂,所需的CPU时间将相应增加。
    但是,将位图涂在画布上将始终是恒定时间,该时间与位图的大小成比例。

    2

    不知道什么是"某物",我如何向您展示如何做?
    您应该能够从#3的答案中找出#2。

    3

    假设:

    • bmp1大于bmp2。
    • 您希望它们都从左上角覆盖。

      1
      2
      3
      4
      5
      6
      7
          private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
              Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
              Canvas canvas = new Canvas(bmOverlay);
              canvas.drawBitmap(bmp1, new Matrix(), null);
              canvas.drawBitmap(bmp2, new Matrix(), null);
              return bmOverlay;
          }


    您可以执行以下操作:

    1
    2
    3
    4
    5
    public void putOverlay(Bitmap bitmap, Bitmap overlay) {
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
        canvas.drawBitmap(overlay, 0, 0, paint);
    }

    这个想法非常简单:将位图与画布关联后,就可以调用任何画布的方法来绘制位图。

    这将适用于具有透明度的位图。如果位图具有Alpha通道,则它将具有透明度。查看Bitmap.Config。您可能要使用ARGB_8888。

    重要提示:请查看此Android示例,了解执行绘图的不同方法。它将对您有很大帮助。

    在性能方面(确切地说在内存方面),位图是最好的对象,因为它们只是包装了本机位图。 ImageView是View的子类,并且BitmapDrawable在其中包含一个Bitmap,但是它还包含许多其他内容。但是,这过于简单了。您可以针对特定性能提出建议,以获取准确答案。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public static Bitmap overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2) {
        int bitmap1Width = bitmap1.getWidth();
        int bitmap1Height = bitmap1.getHeight();
        int bitmap2Width = bitmap2.getWidth();
        int bitmap2Height = bitmap2.getHeight();

        float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
        float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);

        Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
        Canvas canvas = new Canvas(overlayBitmap);
        canvas.drawBitmap(bitmap1, new Matrix(), null);
        canvas.drawBitmap(bitmap2, marginLeft, marginTop, null);
        return overlayBitmap;
    }

    我认为这个示例绝对可以帮助您在另一个图像之上叠加一个透明图像。通过在画布上绘制两个图像并返回位图图像,可以实现此目的。

    在此处阅读更多信息或下载演示

    1
    2
    3
    4
    5
    6
    7
    8
    private Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage){

            Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
            Canvas canvas = new Canvas(result);
            canvas.drawBitmap(firstImage, 0f, 0f, null);
            canvas.drawBitmap(secondImage, 10, 10, null);
            return result;
        }

    并在按钮单击时调用上述函数,并将两个图像传递给我们的函数,如下所示

    1
    2
    3
    4
    5
    6
    7
    8
    public void buttonMerge(View view) {

            Bitmap bigImage = BitmapFactory.decodeResource(getResources(), R.drawable.img1);
            Bitmap smallImage = BitmapFactory.decodeResource(getResources(), R.drawable.img2);
            Bitmap mergedImages = createSingleImageFromMultipleImages(bigImage, smallImage);

            img.setImageBitmap(mergedImages);
        }

    对于两个以上的图像,您可以单击此链接,了解如何在Android上以编程方式合并多个图像


    如果目的是获得位图,则非常简单:

    1
    2
    3
    Canvas canvas = new Canvas();
    canvas.setBitmap(image);
    canvas.drawBitmap(image2, new Matrix(), null);

    最后,image将包含image和image2的重叠。


    对于Kotlin粉丝:

  • 你可以创建一个更通用的扩展名:
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     private fun Bitmap.addOverlay(@DimenRes marginTop: Int, @DimenRes marginLeft: Int, overlay: Bitmap): Bitmap? {
            val bitmapWidth = this.width
            val bitmapHeight = this.height
            val marginLeft = shareBitmapWidth - overlay.width - resources.getDimension(marginLeft)
            val finalBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, this
                .config)

            val canvas = Canvas(finalBitmap)
            canvas.drawBitmap(this, Matrix(), null)
            canvas.drawBitmap(overlay, marginLeft, resources.getDimension(marginTop), null)
            return finalBitmap
        }
  • 然后按以下方式使用它:
  • 1
     bitmap.addOverlay( R.dimen.top_margin, R.dimen.left_margin, overlayBitmap)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static Bitmap createSingleImageFromMultipleImages(Bitmap firstImage, Bitmap secondImage, ImageView secondImageView){

        Bitmap result = Bitmap.createBitmap(firstImage.getWidth(), firstImage.getHeight(), firstImage.getConfig());
        Canvas canvas = new Canvas(result);
        canvas.drawBitmap(firstImage, 0f, 0f, null);
        canvas.drawBitmap(secondImage, secondImageView.getX(), secondImageView.getY(), null);

        return result;
    }