• Android:使用ZXing生成二维码(支持加入Logo图案)


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

    首先上效果图:


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

    或者在这里下载(仅仅有本项目所用的jar包,版本:3.2.0):链接: http://pan.baidu.com/s/1hq3s5EW password: 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.本项目中图片文件保存在

    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" />
    因此,个人推測。所谓的不须要权限是从 Android 4.4.4開始的。





  • 相关阅读:
    一个十分诡异的NullReferenceException异常!
    如何去掉TabControl控件默认添加的TabPage
    GDI+发生一般性错误的解决方法
    C#中各种数组的性能比较
    酷享娱乐新生活
    关于ImageList.Images集合的特殊行为!
    WinForm窗体之间交互的一些方法
    实现单实例应用程序的三种方案
    MySql_Close 释放资源
    数组之List
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7222973.html
Copyright © 2020-2023  润新知