最近,接到一个保存带背景的二维码的需求,想了想,干脆两个bitmap合成一个,下面是完成该需求的过程
一.生成二维码工具类
public class QRCodeUtil {
/**
* 创建二维码位图
*
* @param content 字符串内容(支持中文)
* @param width 位图宽度(单位:px)
* @param height 位图高度(单位:px)
* @return
*/
@Nullable
public static Bitmap createQRCodeBitmap(String content, int width, int height) {
return createQRCodeBitmap( content, width, height, "UTF-8", "H", "2", Color.BLACK, Color.WHITE );
}
/**
* 创建二维码位图 (支持自定义配置和自定义样式)
*
* @param content 字符串内容
* @param width 位图宽度,要求>=0(单位:px)
* @param height 位图高度,要求>=0(单位:px)
* @param margin 空白边距 (可修改,要求:整型且>=0), 传null时,zxing源码默认使用"4"。
* @param color_black 黑色色块的自定义颜色值
* @param color_white 白色色块的自定义颜色值
* @return
*/
@Nullable
public static Bitmap createQRCodeBitmap(String content, int width, int height,
@Nullable String character_set, @Nullable String error_correction, @Nullable String margin,
@ColorInt int color_black, @ColorInt int color_white) {
/** 1.参数合法性判断 */
if (TextUtils.isEmpty( content )) { // 字符串内容判空
return null;
}
if (width < 0 || height < 0) { // 宽和高都需要>=0
return null;
}
try {
/** 2.设置二维码相关配置,生成BitMatrix(位矩阵)对象 */
Hashtable<EncodeHintType, String> hints = new Hashtable<>();
if (!TextUtils.isEmpty( character_set )) {
hints.put( EncodeHintType.CHARACTER_SET, character_set ); // 字符转码格式设置
}
if (!TextUtils.isEmpty( error_correction )) {
hints.put( EncodeHintType.ERROR_CORRECTION, error_correction ); // 容错级别设置
}
if (!TextUtils.isEmpty( margin )) {
hints.put( EncodeHintType.MARGIN, margin ); // 空白边距设置
}
BitMatrix bitMatrix = new QRCodeWriter().encode( content, BarcodeFormat.QR_CODE, width, height, hints );
/** 3.创建像素数组,并根据BitMatrix(位矩阵)对象为数组元素赋颜色值 */
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (bitMatrix.get( x, y )) {
pixels[y * width + x] = color_black; // 黑色色块像素设置
} else {
pixels[y * width + x] = color_white; // 白色色块像素设置
}
}
}
/** 4.创建Bitmap对象,根据像素数组设置Bitmap每个像素点的颜色值,之后返回Bitmap对象 */
Bitmap bitmap = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888 );
bitmap.setPixels( pixels, 0, width, 0, 0, width, height );
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
}
return null;
}
}
直接调用该工具类,就可以生成二维码
mBitmap = QRCodeUtil.createQRCodeBitmap( "https://m.csnengyuan.com/signIn?phone=" + mobilephone, 350, 350 );
将二维码展示到Imageview里面
ivZxing.setImageBitmap( mBitmap );
二.生成带UI背景的二维码,和UI背景合二为一,保存到相册
1.本地大背景,UI切图背景
Bitmap bitmap = BitmapFactory.decodeResource( super.getResources(), R.mipmap.icon_bg_share );
2.和刚才生成的二维码合二为一,两个bitmap生成一个
combineBitmap = combineBitmap( bitmap, mBitmap );
3.检查权限,保存二维码图片
if (combineBitmap != null) {
if (EasyPermissions.hasPermissions( AtyZXing.this, perms )) {
saveImageToGallery( AtyZXing.this, combineBitmap );
} else {
// Do not have permissions, request them now
EasyPermissions.requestPermissions( AtyZXing.this, "因为功能需要,需要使用存储权限,请允许",
100, perms );
}
}
4.保存图片的方法
/**
* 保存图片
*
* @time 2019-06-27 17:59
*/
public void saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存图片 创建文件夹
File appDir = new File( Environment.getExternalStorageDirectory(), "昌胜能源" );
if (!appDir.exists()) {
appDir.mkdir();
}
//图片文件名称
String fileName = "csny_" + System.currentTimeMillis() + ".jpg";
File file = new File( appDir, fileName );
try {
FileOutputStream fos = new FileOutputStream( file );
bmp.compress( Bitmap.CompressFormat.JPEG, 100, fos );
fos.flush();
fos.close();
} catch (Exception e) {
Log.e( "111", e.getMessage() );
e.printStackTrace();
}
// 其次把文件插入到系统图库
String path = file.getAbsolutePath();
try {
MediaStore.Images.Media.insertImage( context.getContentResolver(), path, fileName, null );
} catch (FileNotFoundException e) {
Log.e( "333", e.getMessage() );
e.printStackTrace();
}
// 最后通知图库更新
Intent intent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE );
Uri uri = Uri.fromFile( file );
intent.setData( uri );
context.sendBroadcast( intent );
ToastUtil.showToast( "保存成功" );
}
5.生成带UI背景的二维码方法
/**
* 合并两张bitmap为一张
*
* @param background
* @param foreground
* @return Bitmap
*/
public static Bitmap combineBitmap(Bitmap background, Bitmap foreground) {
if (background == null) {
return null;
}
int bgWidth = background.getWidth();
int bgHeight = background.getHeight();
int fgWidth = foreground.getWidth();
int fgHeight = foreground.getHeight();
Bitmap newmap = Bitmap
.createBitmap( bgWidth, bgHeight, Bitmap.Config.ARGB_8888 );
Canvas canvas = new Canvas( newmap );
canvas.drawBitmap( background, 0, 0, null );
canvas.drawBitmap( foreground, (bgWidth - fgWidth) / 2,
(bgHeight - fgHeight) / 2, null );
canvas.save( Canvas.ALL_SAVE_FLAG );
canvas.restore();
return newmap;
}
6.
/**
* 权限的结果回调函数
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult( requestCode, permissions, grantResults );
//把申请权限的回调交由EasyPermissions处理
EasyPermissions.onRequestPermissionsResult( requestCode, permissions, grantResults, new EasyPermissions.PermissionCallbacks() {
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
//LogUtil.e("获取成功的权限" + perms);
saveImageToGallery( AtyZXing.this, combineBitmap );
}
//拒绝授权
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
// showMissingPermissionDialog();
}
@Override
public void onRequestPermissionsResult(int i, @NonNull String[] strings, @NonNull int[] ints) {
}
} );
}