【问题标题】:Android: How to overlay a bitmap and draw over a bitmap?Android:如何覆盖位图并在位图上绘制?
【发布时间】:2010-12-05 03:29:55
【问题描述】:

其实我有三个问题:

  1. 是在位图上绘制图像还是创建位图作为资源然后在位图上绘制更好?性能方面,哪个更好?
  2. 如果我想在位图上绘制透明的东西,我该怎么做?
  3. 如果我想将一个透明位图叠加到另一个上,我该怎么做?

抱歉,列表太长了,但为了学习,我想探索这两种方法。

【问题讨论】:

    标签: android graphics drawing bitmap overlay


    【解决方案1】:

    我不敢相信还没有人回答这个问题! SO上罕见的出现!

    1

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

    2

    如果不知道“某事”是什么,我怎么能告诉你怎么做呢? 您应该能够从#3 的答案中找出#2。

    3

    假设:

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

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

    【讨论】:

    • @Declan Shanaghy 这是完美的工作。也可以使用drawBitmap(Bitmap bitmap, float left, float top, Paint paint) 进行定位,阅读文档here
    • 我有 900 张图像想要将图像叠加到其中。它工作得非常好,但为什么它非常慢:(一口气真的很花时间
    • 九百! :)
    • 如何从左下角开始绘图? @Declan
    【解决方案2】:

    你可以这样做:

    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。

    重要提示:查看this Android 示例,了解执行绘图的不同方式。对你有很大帮助。

    性能方面(确切地说是内存方面),位图是最适合使用的对象,因为它们只是包装了一个原生位图。 ImageView 是 View 的子类,BitmapDrawable 内部包含一个 Bitmap,但它也包含许多其他内容。但这是过于简单化了。您可以建议一个特定于性能的方案以获得准确的答案。

    【讨论】:

    • 我有 900 张图像想要在其中叠加图像.. 它工作得非常好,但为什么它非常慢:( 真的很耗时
    • 我得到了 IllegalArgumentException... 它说的是不可变位图。
    • (我知道 - 旧评论。但对于可能遇到它的其他人:)bitmap 参数需要是可变位图。查看this blog post,了解如何将不可变位图转换为可变位图或将文件加载到可变位图。
    【解决方案3】:

    如果目的是获取位图,这很简单:

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

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

    【讨论】:

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

      【讨论】:

        【解决方案5】:

        我认为这个示例肯定会帮助您将透明图像叠加到另一个图像之上。这可以通过在画布上绘制图像并返回位图图像来实现。

        阅读更多或下载演示here

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

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

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

        对于两张以上的图片,您可以点击此链接,how to merge multiple images programmatically on android

        【讨论】:

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

          【讨论】:

            【解决方案7】:

            对于 Kotlin 粉丝:

            1. 你可以创建一个更通用的扩展:
             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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-03-21
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-04-08
              • 1970-01-01
              • 2013-07-18
              • 2011-05-08
              相关资源
              最近更新 更多