Android:如何覆盖位图并在位图上绘制?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1540272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android: How to overlay a bitmap and draw over a bitmap?
提问by Legend
I have three questions actually:
其实我有三个问题:
- Is it better to draw an image on a bitmap or create a bitmap as resource and then draw it over a bitmap? Performance wise, which one is better?
- If I want to draw something transparent over a bitmap, how would I go about doing it?
- If I want to overlay one transparent bitmap over another, how would I do it?
- 在位图上绘制图像或创建位图作为资源然后在位图上绘制它更好吗?性能明智,哪个更好?
- 如果我想在位图上绘制透明的东西,我该怎么做?
- 如果我想将一个透明位图覆盖在另一个上,我该怎么做?
Sorry for the long list, but in the interest of learning, I would like to explore both the approaches.
抱歉,列表很长,但为了学习的兴趣,我想探索这两种方法。
回答by Declan Shanaghy
I can't believe no one has answered this yet! A rare occurrence on SO!
我不敢相信还没有人回答这个问题!罕见的发生在 SO!
1
1
The question doesn't quite make sense to me. But I'll give it a stab. If you're asking about direct drawing to a canvas (polygons, shading, text etc...) vs. loading a bitmap and blitting it onto the canvas that would depend on the complexity of your drawing. As the drawing gets more complex the CPU time required will increase accordingly. However, blitting a bitmap onto a canvas will always be a constant time which is proportional to the size of the bitmap.
这个问题对我来说不是很有意义。但我会试一试。如果您问的是直接绘制到画布(多边形、阴影、文本等)与加载位图并将其块传输到画布上,这取决于您的绘图的复杂性。随着绘图变得越来越复杂,所需的 CPU 时间也会相应增加。但是,将位图块传输到画布上将始终是一个与位图大小成正比的恒定时间。
2
2
Without knowing what "something" is how can I show you how to do it? You should be able to figure out #2 from the answer for #3.
在不知道什么是“某事”的情况下,我如何向您展示如何去做?您应该能够从#3 的答案中找出#2。
3
3
Assumptions:
假设:
- bmp1 is larger than bmp2.
You want them both overlaid from the top left corner.
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; }
- 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; }
回答by Lior
You can do something like this:
你可以这样做:
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);
}
The idea is very simple: Once you associate a bitmap with a canvas, you can call any of the canvas' methods to draw over the bitmap.
这个想法很简单:一旦将位图与画布相关联,就可以调用画布的任何方法来绘制位图。
This will work for bitmaps that have transparency. A bitmap will have transparency, if it has an alpha channel. Look at Bitmap.Config. You'd probably want to use ARGB_8888.
这适用于具有透明度的位图。如果位图具有 Alpha 通道,则位图将具有透明度。看看Bitmap.Config。您可能想要使用 ARGB_8888。
Important: Look at thisAndroid sample for the different ways you can perform drawing. It will help you a lot.
重要提示:查看此Android 示例以了解执行绘图的不同方式。它会帮助你很多。
Performance wise (memory-wise, to be exact), Bitmaps are the best objects to use, since they simply wrap a native bitmap. An ImageView is a subclass of View, and a BitmapDrawable holds a Bitmap inside, but it holds many other things as well. But this is an over-simplification. You can suggest a performance-specific scenario for a precise answer.
性能方面(确切地说是内存方面),位图是最好的对象,因为它们只是包装了一个原生位图。ImageView 是 View 的一个子类,一个 BitmapDrawable 在里面保存了一个 Bitmap,但它也保存了许多其他的东西。但这是一种过度简化。您可以建议特定于性能的场景以获得准确的答案。
回答by AnsonChen
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;
}
回答by Daniel Nyamasyo
I think this example will definitely help you overlay a transparent image on top of another image. This is made possible by drawing both the images on canvas and returning a bitmap image.
我认为这个例子肯定会帮助你在另一个图像上叠加一个透明图像。这是通过在画布上绘制图像并返回位图图像来实现的。
Read more or download demo 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;
}
and call the above function on button click and pass the two images to our function as shown below
并在按钮单击时调用上述函数并将两个图像传递给我们的函数,如下所示
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);
}
For more than two images, you can follow this link, how to merge multiple images programmatically on android
对于两个以上的图像,您可以点击此链接,如何在android上以编程方式合并多个图像
回答by Giorgio Barchiesi
If the purpose is to obtain a bitmap, this is very simple:
如果目的是获取位图,这个很简单:
Canvas canvas = new Canvas();
canvas.setBitmap(image);
canvas.drawBitmap(image2, new Matrix(), null);
In the end, image will contain the overlap of image and image2.
最后,image 将包含 image 和 image2 的重叠部分。
回答by Svitlana
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;
}
回答by Fab
For Kotlin fans:
对于 Kotlin 粉丝:
- U can create a more generic extension :
- 你可以创建一个更通用的扩展:
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
}
- Then use it as follow:
- 然后按如下方式使用它:
bitmap.addOverlay( R.dimen.top_margin, R.dimen.left_margin, overlayBitmap)