62

我实际上有三个问题:

  1. 在位图上绘制图像或创建位图作为资源然后将其绘制在位图上会更好吗?性能方面,哪个更好?
  2. 如果我想在位图上绘制透明的东西,我该怎么做呢?
  3. 如果我想将一个透明位图覆盖在另一个上,我该怎么做?

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

4

7 回答 7

116

我不敢相信还没有人回答这个问题!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;
        }
    
于 2010-02-18T08:33:30.867 回答
33

你可以这样做:

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,但它也包含许多其他内容。但这是过于简单化了。您可以建议一个特定于性能的方案以获得准确的答案。

于 2011-01-29T10:45:13.200 回答
16
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;
}
于 2015-10-21T03:32:23.107 回答
2

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

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

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

于 2012-10-19T09:41:34.450 回答
2

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

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

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

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

于 2016-12-19T12:53:09.857 回答
2

对于 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)
于 2019-12-11T19:33:43.530 回答
0
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;
}
于 2017-07-25T10:54:56.160 回答