Android 中 Bitmap 和 Drawable

来源:互联网 发布:显示淘宝下架插件 编辑:程序博客网 时间:2024/05/22 07:53

此前由于太懒暂停维护,现在项目需要,重新维护起我的开源项目:NextQRCode(https://github.com/yoojia/NextQRCode)

在重构新特性中,增加了二维码图片中间的小图标功能,使用到Bitmap和Drawable之间的转换处理。在此对处理方式做个记录,希望有助于同样需求的同学。


Drawable资源转换 Bitmap

二维码图片的处理是基于Bitmap来处理的,所以像添加中间小图标等操作需要将R.drawable.qrcode_center_icon资源转换成Bitmap才能做后续处理。

在AndroidSDK库中有一个工具类BitmapFactory,它可以非常简单地将 drawable 资源转码成 bitmap 对象:

final Bitmap centerIconBitmap = BitmapFactory.decodeResource(context.getResource(), R.drawable.qrcode_center_icon);

需要注意的是,这个方法只能将JPG,PNG之类的图片文件资源转换成Bitmap,对于XML文件创建的Drawable无能为力。

Drawable对象转换成Bitmap

这个方法来自SO:http://stackoverflow.com/a/10600736/4536498

详见下面的转换方法:

public static Bitmap drawableToBitmap (Drawable drawable) {    Bitmap bitmap = null;    if (drawable instanceof BitmapDrawable) {        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;        if(bitmapDrawable.getBitmap() != null) {            return bitmapDrawable.getBitmap();        }    }    if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {        bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel    } else {        bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);    }    Canvas canvas = new Canvas(bitmap);    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());    drawable.draw(canvas);    return bitmap;}

Bitmap 转换成 Drawable

将Bitmap转换成Drawable更简单。

final Drawable drawable = new BitmapDrawable(context.getResource(), srcBitmap);

NextQRCode中使用到其它Bitmap处理方法

1、增加图片Padding

ZXing的EncodeHitType中有一个参数EncodeHintType.MARGIN,它可以设定生成的二维码图片外边距。但是它设定的外边距是以二维码点为单位,比方说设置 EncodeHintType.MARGIN参数值为3,则生成二维码图片外边距尺寸是三个黑点的宽度。

MARGIN外边距

使用二维码点作为单位有些不好控制,我为此增加了以像素为单位的Padding设置。这个处理方法是重建一个空白Bitmap,新的尺寸增加了Padding像素单位的大小,然后用Canvas将原Bitmap绘制到新的Bitmap中。

// 增加Padding,新建Bitmapfinal int newW = srcBitmap.getWidth() + padding * 2;final int newH = srcBitmap.getHeight() + padding * 2;final Bitmap newBitmap = Bitmap.createBitmap(newW, newH, srcBitmap.getConfig());// 绘制原来的Bitmapfinal Canvas canvas = new Canvas(newBitmap);canvas.drawColor(Color.WHITE);canvas.drawBitmap(srcBitmap, padding, padding, null);

实现效果如下,可以精确到像素控制内边距的大小。

Padding

2、在二维码中间增加小图标

二维码有一定级别的容错能力,因此我们可以在二维码中间增加一个小图标。增加图标的方法与上面增加Padding方法类似,是通过Canvas将图标的Bitmap绘制到二维码图片中间。另外图标占二维码的比例不能太高,默认情况下25%已经足够了。

final int resizeW = (int) (srcBitmap.getWidth() * ratio);final int resizeH = (int) (srcBitmap.getHeight() * ratio);final Bitmap newCenterImage = Bitmap.createScaledBitmap(centerImage, resizeW, resizeH, true);final int x = (srcBitmap.getWidth() - resizeW) / 2;final int y = (srcBitmap.getHeight() - resizeH) / 2;final Canvas canvas = new Canvas(srcBitmap);canvas.drawBitmap(newCenterImage, x, y, null);

实现效果跟微信二维码头像一样,见下图:

内嵌小图标

0 0