Android使用ZXing生成带Logo图案的二维码

ZXing是谷歌的一个开源库,可以用来生成二维码、扫描二维码。本文所介绍的是第一部分。

首先上效果图:

ZXing相关各种文件官方下载地址:https://github.com/zxing/zxing/releases 

或者在这里下载(只有本项目所用的jar包,版本号:3.2.0):链接: http://pan.baidu.com/s/1hq3s5EW 密码: mvg7

1.生成二维码的工具类

/** 
     * 二维码生成工具类 
     */  
    public class QRCodeUtil {  
        /** 
         * 生成二维码Bitmap 
         * 
         * @param content   内容 
         * @param widthPix  图片宽度 
         * @param heightPix 图片高度 
         * @param logoBm    二维码中心的Logo图标(可以为null) 
         * @param filePath  用于存储二维码图片的文件路径 
         * @return 生成二维码及保存文件是否成功 
         */  
        public static boolean createQRImage(String content, int widthPix, int heightPix, Bitmap logoBm, String filePath) {  
            try {  
                if (content == null || "".equals(content)) {  
                    return false;  
                }  
      
                //配置参数  
                Map<EncodeHintType, Object> hints = new HashMap<>();  
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
                //容错级别  
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
                //设置空白边距的宽度  
    //            hints.put(EncodeHintType.MARGIN, 2); //default is 4  
      
                // 图像数据转换,使用了矩阵转换  
                BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, widthPix, heightPix, hints);  
                int[] pixels = new int[widthPix * heightPix];  
                // 下面这里按照二维码的算法,逐个生成二维码的图片,  
                // 两个for循环是图片横列扫描的结果  
                for (int y = 0; y < heightPix; y++) {  
                    for (int x = 0; x < widthPix; x++) {  
                        if (bitMatrix.get(x, y)) {  
                            pixels[y * widthPix + x] = 0xff000000;  
                        } else {  
                            pixels[y * widthPix + x] = 0xffffffff;  
                        }  
                    }  
                }  
      
                // 生成二维码图片的格式,使用ARGB_8888  
                Bitmap bitmap = Bitmap.createBitmap(widthPix, heightPix, Bitmap.Config.ARGB_8888);  
                bitmap.setPixels(pixels, 0, widthPix, 0, 0, widthPix, heightPix);  
      
                if (logoBm != null) {  
                    bitmap = addLogo(bitmap, logoBm);  
                }  
      
                //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!  
                return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));  
            } catch (WriterException | IOException e) {  
                e.printStackTrace();  
            }  
      
            return false;  
        }  
      
        /** 
         * 在二维码中间添加Logo图案 
         */  
        private static Bitmap addLogo(Bitmap src, Bitmap logo) {  
            if (src == null) {  
                return null;  
            }  
      
            if (logo == null) {  
                return src;  
            }  
      
            //获取图片的宽高  
            int srcWidth = src.getWidth();  
            int srcHeight = src.getHeight();  
            int logoWidth = logo.getWidth();  
            int logoHeight = logo.getHeight();  
      
            if (srcWidth == 0 || srcHeight == 0) {  
                return null;  
            }  
      
            if (logoWidth == 0 || logoHeight == 0) {  
                return src;  
            }  
      
            //logo大小为二维码整体大小的1/5  
            float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;  
            Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);  
            try {  
                Canvas canvas = new Canvas(bitmap);  
                canvas.drawBitmap(src, 0, 0, null);  
                canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);  
                canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);  
      
                canvas.save(Canvas.ALL_SAVE_FLAG);  
                canvas.restore();  
            } catch (Exception e) {  
                bitmap = null;  
                e.getStackTrace();  
            }  
      
            return bitmap;  
        }  
      
    }


2.在Activity中的使用:

/** 
     * 二维码生成 
     */  
    public class MainActivity extends ActionBarActivity {  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
      
            //内容  
            final EditText contentET = (EditText) findViewById(R.id.create_qr_content);  
            //显示二维码图片  
            final ImageView imageView = (ImageView) findViewById(R.id.create_qr_iv);  
            //是否添加Logo  
            final CheckBox addLogoCB = (CheckBox) findViewById(R.id.create_qr_addLogo);  
            Button createQrBtn = (Button) findViewById(R.id.create_qr_btn);  
      
            createQrBtn.setOnClickListener(new View.OnClickListener() {  
      
                @Override  
                public void onClick(View v) {  
                    final String filePath = getFileRoot(MainActivity.this) + File.separator  
                            + "qr_" + System.currentTimeMillis() + ".jpg";  
      
                    //二维码图片较大时,生成图片、保存文件的时间可能较长,因此放在新线程中  
                    new Thread(new Runnable() {  
                        @Override  
                        public void run() {  
                            boolean success = QRCodeUtil.createQRImage(contentET.getText().toString().trim(), 800, 800,  
                                    addLogoCB.isChecked() ? BitmapFactory.decodeResource(getResources(), R.mipmap.qr_logo) : null,  
                                    filePath);  
      
                            if (success) {  
                                runOnUiThread(new Runnable() {  
                                    @Override  
                                    public void run() {  
                                        imageView.setImageBitmap(BitmapFactory.decodeFile(filePath));  
                                    }  
                                });  
                            }  
                        }  
                    }).start();  
      
                }  
            });  
        }  
      
        //文件存储根目录  
        private String getFileRoot(Context context) {  
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {  
                File external = context.getExternalFilesDir(null);  
                if (external != null) {  
                    return external.getAbsolutePath();  
                }  
            }  
      
            return context.getFilesDir().getAbsolutePath();  
        }  
    }


3.本项目中图片文件保存在3.本项目中图片文件保存在

context.getExternalFilesDir(null)


目录之下的。按照官方的api文档,从KitKat开始(Android 4.4),保存文件到这个目录下将不需要SD卡读写权限。但是经过测验表明,在红米Note和魅族MX3上(系统均为android 4.4.4),的确不需要权限;但是在本人的华为P6上(Android 4.4.2),必须声明权限才能成功的保存文件,即必须在manifest中添加如下内容:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

来自:http://blog.csdn.net/books1958/article/details/46346531

转载于:https://my.oschina.net/u/1177694/blog/885850

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值