精华内容
下载资源
问答
  • 使用Zxing生成带logo二维码

    使用Zxing生成带logo的二维码

    Zxing是Google提供的关于条码(一维码、二维码)的生成和解析工具。Zxing提供了二维码的生成与解析的方法,本文介绍的是使用Zxing生成带logo的二维码


    导入com.google.zxingjar包

    <dependency>
    	<groupId>com.google.zxing</groupId>
    	<artifactId>core</artifactId>
    	<version>3.2.0</version>
    </dependency>

    一下为两个生产二维码的辅助类

    BufferedImageLuminanceSource.java

    package utilities;
    
    import java.awt.Graphics2D;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    
    import com.google.zxing.LuminanceSource;
    
    public class BufferedImageLuminanceSource extends LuminanceSource {
    	private final BufferedImage image;
    	private final int left;
    	private final int top;
    
    	public BufferedImageLuminanceSource(BufferedImage image) {
    		this(image, 0, 0, image.getWidth(), image.getHeight());
    	}
    
    	public BufferedImageLuminanceSource(BufferedImage image, int left,
    			int top, int width, int height) {
    		super(width, height);
    
    		int sourceWidth = image.getWidth();
    		int sourceHeight = image.getHeight();
    		if (left + width > sourceWidth || top + height > sourceHeight) {
    			throw new IllegalArgumentException(
    					"Crop rectangle does not fit within image data.");
    		}
    
    		for (int y = top; y < top + height; y++) {
    			for (int x = left; x < left + width; x++) {
    				if ((image.getRGB(x, y) & 0xFF000000) == 0) {
    					image.setRGB(x, y, 0xFFFFFFFF); // = white
    				}
    			}
    		}
    
    		this.image = new BufferedImage(sourceWidth, sourceHeight,
    				BufferedImage.TYPE_BYTE_GRAY);
    		this.image.getGraphics().drawImage(image, 0, 0, null);
    		this.left = left;
    		this.top = top;
    	}
    
    	
    	public byte[] getRow(int y, byte[] row) {
    		if (y < 0 || y >= getHeight()) {
    			throw new IllegalArgumentException(
    					"Requested row is outside the image: " + y);
    		}
    		int width = getWidth();
    		if (row == null || row.length < width) {
    			row = new byte[width];
    		}
    		image.getRaster().getDataElements(left, top + y, width, 1, row);
    		return row;
    	}
    
    	
    	public byte[] getMatrix() {
    		int width = getWidth();
    		int height = getHeight();
    		int area = width * height;
    		byte[] matrix = new byte[area];
    		image.getRaster().getDataElements(left, top, width, height, matrix);
    		return matrix;
    	}
    
    	
    	public boolean isCropSupported() {
    		return true;
    	}
    
    	
    	public LuminanceSource crop(int left, int top, int width, int height) {
    		return new BufferedImageLuminanceSource(image, this.left + left,
    				this.top + top, width, height);
    	}
    
    	
    	public boolean isRotateSupported() {
    		return true;
    	}
    
    	
    	public LuminanceSource rotateCounterClockwise() {
    		int sourceWidth = image.getWidth();
    		int sourceHeight = image.getHeight();
    		AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0,
    				0.0, 0.0, sourceWidth);
    		BufferedImage rotatedImage = new BufferedImage(sourceHeight,
    				sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
    		Graphics2D g = rotatedImage.createGraphics();
    		g.drawImage(image, transform, null);
    		g.dispose();
    		int width = getWidth();
    		return new BufferedImageLuminanceSource(rotatedImage, top,
    				sourceWidth - (left + width), getHeight(), width);
    	}
    }
    

    QRCodeUtil.java

    package utilities;
    
    import java.awt.BasicStroke;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Shape;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.OutputStream;
    import java.util.Hashtable;
    import java.util.UUID;
    
    import javax.imageio.ImageIO;
    
    import org.springframework.stereotype.Component;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.Result;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    /**
     * 二维码工具类
     * 
     */
    @Component("qRCodeUtil")
    public class QRCodeUtil {
    
    	private static final String CHARSET = "utf-8";
    	private final String FORMAT_NAME = "JPG";
    	// 二维码尺寸
    	private final int QRCODE_SIZE = 600;
    	// LOGO宽度
    	private final int WIDTH = 150;
    	// LOGO高度
    	private final int HEIGHT = 150;
    
    	private BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception {
    		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    		hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    		hints.put(EncodeHintType.MARGIN, 1);
    		BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
    		int width = bitMatrix.getWidth();
    		int height = bitMatrix.getHeight();
    		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    		for (int x = 0; x < width; x++) {
    			for (int y = 0; y < height; y++) {
    				image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
    			}
    		}
    		if (imgPath == null || "".equals(imgPath)) {
    			return image;
    		}
    		// 插入图片
    		this.insertImage(image, imgPath, needCompress);
    		return image;
    	}
    
    	/**
    	 * 插入LOGO
    	 * 
    	 * @param source
    	 *            二维码图片
    	 * @param imgPath
    	 *            LOGO图片地址
    	 * @param needCompress
    	 *            是否压缩
    	 * @throws Exception
    	 */
    	private void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
    		File file = new File(imgPath);
    		if (!file.exists()) {
    			System.err.println("" + imgPath + "   该文件不存在!");
    			return;
    		}
    		Image src = ImageIO.read(new File(imgPath));
    		int width = src.getWidth(null);
    		int height = src.getHeight(null);
    		if (needCompress) { // 压缩LOGO
    			if (width > WIDTH) {
    				width = WIDTH;
    			}
    			if (height > HEIGHT) {
    				height = HEIGHT;
    			}
    			Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
    			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    			Graphics g = tag.getGraphics();
    			g.drawImage(image, 0, 0, null); // 绘制缩小后的图
    			g.dispose();
    			src = image;
    		}
    		// 插入LOGO
    		Graphics2D graph = source.createGraphics();
    		int x = (QRCODE_SIZE - width) / 2;
    		int y = (QRCODE_SIZE - height) / 2;
    		graph.drawImage(src, x, y, width, height, null);
    		Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
    		graph.setStroke(new BasicStroke(3f));
    		graph.draw(shape);
    		graph.dispose();
    	}
    
    	/**
    	 * 生成二维码(内嵌LOGO)
    	 * 
    	 * @param content
    	 *            内容
    	 * @param imgPath
    	 *            LOGO地址
    	 * @param destPath
    	 *            存放目录
    	 * @param needCompress
    	 *            是否压缩LOGO
    	 * @throws Exception
    	 */
    	public String encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
    		BufferedImage image = this.createImage(content, imgPath, needCompress);
    		mkdirs(destPath);
    		// String uuid = UUID.randomUUID().toString();
    		String file = UUID.randomUUID() + ".jpg";
    		ImageIO.write(image, FORMAT_NAME, new File(destPath + File.separator + file));
    		return file;
    	}
    
    	/**
    	 * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    	 * 
    	 * @author lanyuan Email: mmm333zzz520@163.com
    	 * @date 2013-12-11 上午10:16:36
    	 * @param destPath
    	 *            存放目录
    	 */
    	public void mkdirs(String destPath) {
    		File file = new File(destPath);
    		// 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    		if (!file.exists() && !file.isDirectory()) {
    			file.mkdirs();
    		}
    	}
    
    	/**
    	 * 生成二维码(内嵌LOGO)
    	 * 
    	 * @param content
    	 *            内容
    	 * @param imgPath
    	 *            LOGO地址
    	 * @param destPath
    	 *            存储地址
    	 * @throws Exception
    	 */
    	public void encode(String content, String imgPath, String destPath) throws Exception {
    		this.encode(content, imgPath, destPath, false);
    	}
    
    	/**
    	 * 生成二维码
    	 * 
    	 * @param content
    	 *            内容
    	 * @param destPath
    	 *            存储地址
    	 * @param needCompress
    	 *            是否压缩LOGO
    	 * @throws Exception
    	 */
    	public void encode(String content, String destPath, boolean needCompress) throws Exception {
    		this.encode(content, null, destPath, needCompress);
    	}
    
    	/**
    	 * 生成二维码
    	 * 
    	 * @param content
    	 *            内容
    	 * @param destPath
    	 *            存储地址
    	 * @throws Exception
    	 */
    	public void encode(String content, String destPath) throws Exception {
    		this.encode(content, null, destPath, false);
    	}
    
    	/**
    	 * 生成二维码(内嵌LOGO)
    	 * 
    	 * @param content
    	 *            内容
    	 * @param imgPath
    	 *            LOGO地址
    	 * @param output
    	 *            输出流
    	 * @param needCompress
    	 *            是否压缩LOGO
    	 * @throws Exception
    	 */
    	public void encode(String content, String imgPath, OutputStream output, boolean needCompress) throws Exception {
    		BufferedImage image = this.createImage(content, imgPath, needCompress);
    		ImageIO.write(image, FORMAT_NAME, output);
    	}
    
    	/**
    	 * 生成二维码
    	 * 
    	 * @param content
    	 *            内容
    	 * @param output
    	 *            输出流
    	 * @throws Exception
    	 */
    	public void encode(String content, OutputStream output) throws Exception {
    		this.encode(content, null, output, false);
    	}
    
    	/**
    	 * 解析二维码
    	 * 
    	 * @param file
    	 *            二维码图片
    	 * @return
    	 * @throws Exception
    	 */
    	public static String decode(File file) throws Exception {
    		BufferedImage image;
    		image = ImageIO.read(file);
    		if (image == null) {
    			return null;
    		}
    		BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
    		BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    		Result result;
    		Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
    		hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
    		result = new MultiFormatReader().decode(bitmap, hints);
    		String resultStr = result.getText();
    		return resultStr;
    	}
    
    	/**
    	 * 解析二维码
    	 * 
    	 * @param path
    	 *            二维码图片地址
    	 * @return
    	 * @throws Exception
    	 */
    	public String decode(String path) throws Exception {
    		return QRCodeUtil.decode(new File(path));
    	}
    
    	public static void main(String[] args) throws Exception {
    		String text = "http://112.74.92.97";
    		QRCodeUtil.encode(text, "C:\\Users\\iteas1\\Desktop\\divingtime.jpg","C:\\Users\\iteas1\\Desktop\\", true);
    	}
    }
    

    上面两个工具类可以生成带logo的二维码,具体测试看QRCodeUtil.java的main函数

    展开全文
  • Android 使用ZXing生成带logo二维码 有一段时间没有写博客了,都快忘记怎么写了,最近在赶公司的项目,接近尾声了,写点有意思的东西,好了,进入正题。。。 老规矩,从头开始啊,新建一个名为QGCodeDemo的项目 ...

    Android 使用ZXing生成带logo的二维码

    有一段时间没有写博客了,都快忘记怎么写了,最近在赶公司的项目,接近尾声了,写点有意思的东西,好了,进入正题。。。

    老规矩,从头开始啊,新建一个名为QGCodeDemo的项目

    运行效果如下:
    在这里插入图片描述

    然后这里我们会使用一个框架,二维码框架ZXing 划重点,首先我们在app下的build.gradle下添加依赖

    	//二维码
        implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    

    添加之后记得 Sync Now 一下,这个通常出现在AS的右上角,现在框架已经添加进来了,然后就是简单的一个布局,一个按钮,一个居中显示图片

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.lanjing.qgcodedemo.MainActivity">
    
        <ImageView
            android:id="@+id/code"
            android:layout_centerInParent="true"
            android:layout_width="300dp"
            android:layout_height="300dp" />
    
        <Button
            android:id="@+id/showBtn"
            android:text="SHOW CODE"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>
    

    可以看到布局非常简单,然后在MainActivity中进行初始化控件。

    package com.lanjing.qgcodedemo;
    
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.net.Uri;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.ImageView;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private ImageView codeImageView;
        private Button showBtn;
    
        //创建两个Bitmap,一个放二维码,一个放logo
        Bitmap codeBmp, logoBmp;
        private String url;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            showBtn.setOnClickListener(this);
            //给图片添加长按点击事件
            codeImageView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    /*
                    * 给button添加长按事件,触发时调用openCode()方法打开二维码,如果是文本则显示文本,是可访问地址,则会弹出提示问你是否继续访问
                    * */
                    openCode();
                    return true;
                }
            });
        }
    
        //初始化控件
        private void initView() {
            codeImageView = (ImageView) findViewById(R.id.code);
            showBtn = (Button) findViewById(R.id.showBtn);
        }
    
    
        @Override
        public void onClick(View v) {
    
            /*
            * 按钮点击显示二维码
            * */
            //加一个测试地址,之后我们的二维码就是用这个地址来生成。扫描后直接进入百度,这个地址也可以用于动态,或者是你从服务器中得到的地址
            url = "https://www.baidu.com";
            //这里的logo是系统自带的,通过BitmapFactory加载进来
            logoBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.demo);
            //通过ZXing框架将地址和logo图片加到里面,生成二维码之后赋值给codeBmp;
            codeBmp = ZXingUtilsTest.createQRImage(this, url, logoBmp);
            //最后将得到的codeBmp设置为ImageView的ImageBitmap这样图片就会显示出来了
            codeImageView.setImageBitmap(codeBmp);
        }
        
    
        private void openCode() {//这个方法其实和我们之前的页面跳转比较像  intent携带信息访问权限,这时活动产生一个新的任务,然后开始执行这个任务
            Intent intent = new Intent(Intent.ACTION_VIEW,
                    (Uri.parse(url))
            ).addCategory(Intent.CATEGORY_BROWSABLE)
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    
    }
    
    

    应该是一目了然吧,接下来就需要用到ZXing框架的东西了,首先这是一个比较早的框架了,很多人进行了多次重写与封装,里面内容会很多,但不一定适用于现在的你,所以也重写一下这个。

    package com.lanjing.qgcodedemo;
    
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Canvas;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Created by Administrator on 2019/4/3 0001.
     */
    
    public class ZXingUtilsTest {
        /**
         * 生成二维码Bitmap
         *
         * @param context   文本内容
         * @param logoBm    二维码中心的Logo图标(可以为null)
         * @return 合成后的bitmap
         */
        public static Bitmap createQRImage(Context context, String data, Bitmap logoBm) {
    
            try {
    
                if (data == null || "".equals(data)) {
                    return null;
                }
    
                int widthPix = ((Activity) context).getWindowManager().getDefaultDisplay()
                        .getWidth();
                widthPix = widthPix / 5 * 3;
                int heightPix = widthPix;
    
                //配置参数
                Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
                //容错级别
                hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
                //设置空白边距的宽度
                hints.put(EncodeHintType.MARGIN, 3); //default is 4
    
    
                // 图像数据转换,使用了矩阵转换
                BitMatrix bitMatrix = new QRCodeWriter().encode(data, 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);
                }
    
                return bitmap;
                //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
                //return bitmap != null && bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(filePath));
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * 在二维码中间添加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;
        }
    }
    
    

    这个就是一个重写的工具类,可以复制过去直接用。里面也有相关的注释,我就不做过多解释了

    源码地址:CodeDemo

    展开全文
  • Zxing生成二维码含有LOGO package com.example.mvptest;import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.support.v7.app....
    Zxing生成二维码含有LOGO
    
    
    package com.example.mvptest;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Matrix;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.ImageView;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.WriterException;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.QRCodeWriter;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    import java.security.spec.EncodedKeySpec;
    import java.util.Hashtable;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final int QR_WIDTH = 1000;
        private static final int QR_HEIGHT = 1000;
        private static  int IMAGE_HALFWIDTH = 800;
        private ImageView targetImager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            targetImager = (ImageView) findViewById(R.id.iv_QRImage);
            String url = "我是^(* ̄(oo) ̄)^,你呢?afasdfdsa";
            createQRImage(url);
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.ic_launcher);
            Bitmap codeWithLogo = createQRCodeWithLogo(url, bitmap);
            targetImager.setImageBitmap(codeWithLogo);
        }
            /**
             * 生成带logo的二维码,默认二维码的大小为500,logo为二维码的1/5
             *
             * @param text 需要生成二维码的文字、网址等
             * @param mBitmap logo文件
             * @return bitmap
             */
            public static Bitmap createQRCodeWithLogo(String text, Bitmap mBitmap) {
                return createQRCodeWithLogo(text,500,mBitmap);
            }
            /**
             * 生成带logo的二维码,logo默认为二维码的1/5
             *
             * @param text 需要生成二维码的文字、网址等
             * @param size 需要生成二维码的大小()
             * @param mBitmap logo文件
             * @return bitmap
             */
            public static Bitmap createQRCodeWithLogo(String text, int size, Bitmap mBitmap) {
                try {
                    IMAGE_HALFWIDTH = size/10;
                    Hashtable<EncodeHintType, Object> hints = new Hashtable<>();
                    hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
                /*
                 * 设置容错级别,默认为ErrorCorrectionLevel.L
                 * 因为中间加入logo所以建议你把容错级别调至H,否则可能会出现识别不了
                 */
                    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
                    BitMatrix bitMatrix = new QRCodeWriter().encode(text,
                            BarcodeFormat.QR_CODE, size, size, hints);
    
                    int width = bitMatrix.getWidth();//矩阵高度
                    int height = bitMatrix.getHeight();//矩阵宽度
                    int halfW = width / 2;
                    int halfH = height / 2;
    
                    Matrix m = new Matrix();
                    float sx = (float) 2 * IMAGE_HALFWIDTH / mBitmap.getWidth();
                    float sy = (float) 2 * IMAGE_HALFWIDTH
                            / mBitmap.getHeight();
                    m.setScale(sx, sy);
                    //设置缩放信息
                    //将logo图片按martix设置的信息缩放
                    mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
                            mBitmap.getWidth(), mBitmap.getHeight(), m, false);
    
                    int[] pixels = new int[size * size];
                    for (int y = 0; y < size; y++) {
                        for (int x = 0; x < size; x++) {
                            if (x > halfW - IMAGE_HALFWIDTH && x < halfW + IMAGE_HALFWIDTH
                                    && y > halfH - IMAGE_HALFWIDTH
                                    && y < halfH + IMAGE_HALFWIDTH) {
                                //该位置用于存放图片信息
                                //记录图片每个像素信息
                                pixels[y * width + x] = mBitmap.getPixel(x - halfW
                                        + IMAGE_HALFWIDTH, y - halfH + IMAGE_HALFWIDTH);
                            } else {
                                if (bitMatrix.get(x, y)) {
                                    pixels[y * size + x] = 0xff000000;
                                } else {
                                    pixels[y * size + x] = 0xffffffff;
                                }
                            }
                        }
                    }
                    Bitmap bitmap = Bitmap.createBitmap(size, size,
                            Bitmap.Config.ARGB_8888);
                    bitmap.setPixels(pixels, 0, size, 0, 0, size, size);
                    return bitmap;
                } catch (WriterException e) {
                    e.printStackTrace();
                    return null;
                }
        }
    
        private void createQRImage(String url) {
    
            try {
                if (url == null || "".equals(url) || url.length() < 1) {
                    return;
                }
                Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
                hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
    
                //图像数据转换,使用矩阵转换
                BitMatrix bitMatrix = null;
                bitMatrix = new QRCodeWriter().encode(url, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);
                int[] pixels = new int[QR_WIDTH * QR_HEIGHT];
                //下面这里按照二维码的算法,逐个生成二维码的图片,
                //两个for循环是图片横列扫描的结果
                for (int y = 0; y < QR_HEIGHT; y++) {
                    for (int x = 0; x < QR_WIDTH; x++) {
                        if (bitMatrix.get(x, y)) {
                            pixels[y * QR_WIDTH + x] = 0xff000000;
                        } else {
                            pixels[y * QR_WIDTH + x] = 0xffffffff;
                        }
                    }
                }
                //生成二维码图片的格式,使用ARGB_8888
                Bitmap bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888);
                bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
                //显示到一个ImageView上面
                targetImager.setImageBitmap(bitmap);
            } catch (WriterException e) {
                e.printStackTrace();
            }
        }
    }
    
    展开全文
  • 使用zxing生成带logo二维码图片,自动调节logo图片相对二维码图片的大小 可选是否带logo,可选是否保存二维码图片;结果返回base64编码的图片数据字符串 页面显示: 引用maven zxing-core jar com.google.zxing...
    使用zxing生成带logo的二维码图片,自动调节logo图片相对二维码图片的大小
    
     * 可选是否带logo,可选是否保存二维码图片;结果返回base64编码的图片数据字符串
     * 页面显示:<img src="data:image/png;base64,${imageBase64QRCode}"/>
     * maven jar
     * <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.1.0</version>

        </dependency>

    二维码生成工具类下载:点击打开链接

    原作者 http://www.kancloud.cn/digest/javaxviii/126763

    我自己拿来修改定制了下


    1.有logo的二维码


    2.没有logo的二维码


    3.列表直接读取保存在数据库中的二维码base64编码的字符串,显示到页面



    工具类,可以自己定制实现生成图片大小等:

    package com.niuhuohuo.assets.utils;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    import org.apache.commons.codec.binary.Base64;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.WriterException;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    /**
     * 使用zxing生成带logo的二维码图片,自动调节logo图片相对二维码图片的大小
     * 可选是否带logo,可选是否保存二维码图片;结果返回base64编码的图片数据字符串
     * 页面显示:<img src="data:image/png;base64,${imageBase64QRCode}"/>
     * maven jar
     * <dependency>
    	    <groupId>com.google.zxing</groupId>
    	    <artifactId>core</artifactId>
    	    <version>3.1.0</version>
    	</dependency>
     * @author nhhyx
     * @date 20170314
     */
    public class ZXingCodeUtils {
    	private static final int QRCOLOR = 0xFF000000;   //默认是黑色
        private static final int BGWHITE = 0xFFFFFFFF;   //背景颜色
    
        public static void main(String[] args) throws WriterException  
        {  
            try  
            {  
            	/* 调用试例1,从项目中获取logo图片,生成的二维码图片也保存到项目指定文件夹中,使用myeclipse等时,生成的二维码图片在tomcat/webapps/项目中 */        	
            	// 生成二维码图片并将base64编码的数据更新到数据库,data:image/png;base64,***
    			// logo图片
    			/*String logoUrl = request.getSession().getServletContext()
    					.getRealPath("/WEB-INF/assets/admin/img/temp/logo.png");
    		    File logoFile = new File(logoUrl);
            	// 输出二维码路径
            	String outPath = request.getSession().getServletContext()
    					.getRealPath("/WEB-INF/assets/qr"); 
            	String base64Img = ZXingCodeUtils.createQRCode(logoFile, "这是二维码里面的内容,可以是http网址", outPath, 
            			400, 400, "这是二维码图片下的文字,随图片一起生成");*/
            	
            	/* 调用试例2 */ 
            	//String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";
            	/* logo图片路径和二维码输出路径
            	String logoUrl = request.getSession().getServletContext()
    					.getRealPath("/WEB-INF/assets/admin/img/temp/logo.png");
            	String outPath = request.getSession().getServletContext()
    					.getRealPath("/WEB-INF/assets/qr");*/
            	//filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好
            	String logoPath = "C:\\logo.png";
            	File logoFile = new File(logoPath);
            	String outPath = "C:";
            	createQRCode(logoFile, "2asdf5", outPath, 400, 400, "这是二维码下的文字");
            }  
            catch (Exception e)  
            {  
                e.printStackTrace();  
            }  
        }  
    
        /**
         * 生成带logo的二维码图片
         * @param logoPath 二维码图片中间包含的logo图片文件,如果不存在,则生成不带logo图片的二维码
         * @param content 内容或跳转路径
         * @param outPath 二维码输出路径,如果为""则表示不输出图片到指定位置,只返回base64图片字符串
         * @param qrImgWidth 二维码图片宽度
         * @param qrImgHeight 二维码图片高度(有文字的话会加高45px)
         * @param productName 二维码图片下的文字
         * @return
         */
        public static String createQRCode(File logoFile, String content, String outPath, 
        		int qrImgWidth, int qrImgHeight, String productName)
        {
            try
            {  
            	ZXingCodeUtils zp = new ZXingCodeUtils();
            	// 生成二维码bufferedImage图片
                BufferedImage bim = zp.getQRCODEBufferedImage(content, BarcodeFormat.QR_CODE, qrImgWidth, qrImgHeight, zp.getDecodeHintType());
                
                // 如果有文字,则二维码图片高度增加45px
                if(!"".equals(productName)){
                	qrImgHeight += 45;
            	}
                // 给二维码图片添加Logo并保存到指定位置,返回base64编码的图片数据字符串
                return zp.createLogoQRCode(outPath, qrImgWidth, qrImgHeight, bim, logoFile, new LogoConfig(), productName);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 给二维码图片添加Logo图片并生成最终二维码图片
         * @param outPath 输出二维码图片的路径,如果为""则表示不输出图片到指定位置,只返回base64图片字符串
         * @param qrImgWidth 生成二维码图片的宽度
         * @param qrImgHeight 生成二维码图片的高度
         * @param bim 读取二维码图片BufferedImage对象
         * @param logoPic logo图片File文件
         * @param logoConfig logo配置
         * @param productName 二维码图片下的文字
         * @return 返回图片base64编码后的字符串
         */
        public String createLogoQRCode(String outPath, int qrImgWidth, int qrImgHeight, BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName)
        {
            try
            {
                /**
                 * 读取二维码图片,并构建绘图对象
                 */
                BufferedImage image = bim;
                
                // 如果logo图片存在,则加入到二维码图片中
                if(logoPic != null && logoPic.exists()){
    	            Graphics2D g = image.createGraphics();
    	
    	            /**
    	             * 读取Logo图片
    	             */
    	            BufferedImage logo = ImageIO.read(logoPic);
    	            /**
    	             * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
    	             */
    	            int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null), 
    	                heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);
    	
    	            /**
    	             * logo放在中心
    	             */
    	             int x = (image.getWidth() - widthLogo) / 2;
    	             int y = (image.getHeight() - heightLogo) / 2;
    	             /**
    	             * logo放在右下角
    	             *  int x = (image.getWidth() - widthLogo);
    	             *  int y = (image.getHeight() - heightLogo);
    	             */
    
    	            //开始绘制图片
    	            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
    //            	g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
    //            	g.setStroke(new BasicStroke(logoConfig.getBorder()));
    //            	g.setColor(logoConfig.getBorderColor());
    //            	g.drawRect(x, y, widthLogo, heightLogo);
                	g.dispose();
                	
                	logo.flush();
                }
    
                //把商品名称添加上去,商品名称不要太长,这里最多支持两行。太长就会自动截取
                if (productName != null && !productName.equals("")) {
                    //新的图片,把带logo的二维码下面加上文字
                    BufferedImage outImage = new BufferedImage(qrImgWidth, qrImgHeight, BufferedImage.TYPE_4BYTE_ABGR);
                    Graphics2D outg = outImage.createGraphics();
                    //画二维码到新的面板
                    outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
                    //画文字到新的面板
                    outg.setColor(Color.BLACK); 
                    outg.setFont(new Font("宋体",Font.BOLD, 26)); //字体、字型、字号 
                    int strWidth = outg.getFontMetrics().stringWidth(productName);
                    if (strWidth > 399) {
    //                  //长度过长就截取前面部分
    //                  outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字
                        //长度过长就换行
                        String productName1 = productName.substring(0, productName.length()/2);
                        String productName2 = productName.substring(productName.length()/2, productName.length());
                        int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
                        int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
                        outg.drawString(productName1, 200  - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );
                        BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR);
                        Graphics2D outg2 = outImage2.createGraphics();
                        outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                        outg2.setColor(Color.BLACK); 
                        outg2.setFont(new Font("宋体", Font.BOLD, 26)); //字体、字型、字号 
                        outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
                        outg2.dispose(); 
                        outImage2.flush();
                        outImage = outImage2;
                    }else {
                        outg.drawString(productName, 200  - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //画文字 
                    }
                    outg.dispose(); 
                    outImage.flush();
                    image = outImage;
                }
                //logo.flush();
                image.flush();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                baos.flush();
                ImageIO.write(image, "png", baos);
    
                // 如果输出路径为空,则不保存二维码图片到指定路径下
                if(!"".equals(outPath.trim())){
    	            //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉
    	            //可以看到这个方法最终返回的是这个二维码的imageBase64字符串
    	            //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}对应二维码的imageBase64字符串
    	            ImageIO.write(image, "png", new File(outPath + "\\" + new Date().getTime() + ".png"));   
                }
                
                // 获取base64编码的二维码图片字符串
                String imageBase64QRCode = Base64.encodeBase64String(baos.toByteArray());
                baos.close();
                return imageBase64QRCode;
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 构建初始化二维码
         *
         * @param bm
         * @return
         */
        public BufferedImage fileToBufferedImage(BitMatrix bm)
        {
            BufferedImage image = null;
            try
            {
                int w = bm.getWidth(), h = bm.getHeight();
                image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    
                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
                    }
                }
    
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return image;
        }
    
        /**
         * 生成二维码bufferedImage图片
         *
         * @param content
         *            编码内容
         * @param barcodeFormat
         *            编码类型
         * @param width
         *            图片宽度
         * @param height
         *            图片高度
         * @param hints
         *            设置参数
         * @return
         */
        public BufferedImage getQRCODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints)
        {
            MultiFormatWriter multiFormatWriter = null;
            BitMatrix bm = null;
            BufferedImage image = null;
            try
            {
                multiFormatWriter = new MultiFormatWriter();
                // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数
                bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);
                int w = bm.getWidth();
                int h = bm.getHeight();
                image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    
                // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色
                for (int x = 0; x < w; x++)
                {
                    for (int y = 0; y < h; y++)
                    {
                        image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);
                    }
                }
            }
            catch (WriterException e)
            {
                e.printStackTrace();
            }
            return image;
        }
    
        /**
         * 设置二维码的格式参数
         *
         * @return
         */
        public Map<EncodeHintType, Object> getDecodeHintType()
        {
            // 用于设置QR二维码参数
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            // 设置QR二维码的纠错级别(H为最高级别)具体级别信息
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            // 设置编码方式
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            hints.put(EncodeHintType.MARGIN, 0);
            hints.put(EncodeHintType.MAX_SIZE, 350);
            hints.put(EncodeHintType.MIN_SIZE, 100);
    
            return hints;
        }
    }
    
    /**
     * logo的配置
     * @author nhhyx
     *
     */
    class LogoConfig
    {
        // logo默认边框颜色
        public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
        // logo默认边框宽度
        public static final int DEFAULT_BORDER = 2;
        // logo大小默认为照片的1/5
        public static final int DEFAULT_LOGOPART = 5;
    
        private final int border = DEFAULT_BORDER;
        private final Color borderColor;
        private final int logoPart;
    
        /**
         * Creates a default config with on color {@link #BLACK} and off color
         * {@link #WHITE}, generating normal black-on-white barcodes.
         */
        public LogoConfig()
        {
            this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
        }
    
        public LogoConfig(Color borderColor, int logoPart)
        {
            this.borderColor = borderColor;
            this.logoPart = logoPart;
        }
    
        public Color getBorderColor()
        {
            return borderColor;
        }
    
        public int getBorder()
        {
            return border;
        }
    
        public int getLogoPart()
        {
            return logoPart;
        }
    }
    


    展开全文
  • 使用zxing生成带logo二维码图片

    千次阅读 2016-10-19 17:41:29
    很多时候需要我们在生成二维码中间加logo图片,二维码logo图片,思想很简单就是:就是将logo图片叠加到生成二维码图片中间,两个图片叠加一起就是了。但是会遇到一个问题,如果logo加得太大的话,会导致二维码...
  • Android利用ZXing生成帶LOGO的二維碼圖片*本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家發布前言:昨天有個小伙伴問我怎么動態生成帶logo的二維碼,雖然我也見過帶logo的二維碼,但是不知道具體實現,我猜想...
  • java+zxing生成带logo二维码 观前提示: 本文所使用的IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141。 本文所用的是zxing包生成的二维码,为Maven管理的java项目,直接上代码。 pom.xml 引用部分代码 <...
  • java使用zxing生成带logo二维码图片

    千次阅读 2016-08-15 12:53:07
    但是有一个问题就是zxing.3.2.1版本是Java1.7编译的,所以如果我们需要java1.6以及以下版本兼容的话,可以使用如下代码: 这个版本的zxing.jar包:[http://pan.baidu.com/s/1c1a4f6K] package hp.test;
  • Zxing依赖 implementation 'cn.bingoogolapple:bga-qrcode-zxing:1.2.1' 代码段 import android.graphics.Bitmap; import android.graphics.Matrix; import com.google.zxing.BarcodeFormat; import ...
  • 1.前言此工具类作为java项目使用google开源项目zxing生成和解析二维码.代码已添加注释.至于二维码的原理以及zxing的Api请自行百度.2.代码实现dependency: 使用zxing需要先导入jar包,这里使用maven依赖&lt;...
  • java使用zxing生成带logo,文字说明二维码
  • 随着二维码的普及,二维码在生活中的使用使用的场景也越来越来多,本文章就来介绍使用zxing生成与解析二维码生成二维码的开源项目很多,选择zxing则是因为其出自Google并且长期有人进行维护,值得信赖。 ...
  • 昨天有个小伙伴问我怎么动态生成带logo二维码,虽然我也见过带logo二维码,但是不知道具体实现,我猜想ZXing能直接生成带logo二维码吧。于是我去百度了一番,结果都是需要图片合成的。想了一下,二维码的主要...
  • 最近公司需要使用二维码实现产品信息标记,无奈没有自己的生成方式,一直用草料二维码,感觉怪怪的。 二、代码类 2.1、引入依赖 <!-- 引入二维码依赖 --> <dependency> <groupId>...
  • 利用Zxing生成带LOGO二维码图片

    千次阅读 2016-09-02 17:03:49
    利用ZXing生成带LOGO二维码图片 原创 2016-06-20 天际空痕 郭霖 新的一周开始了。 本篇文章的作者 天际空痕(天空) 是我的dota群中的一位成员,虽说水平很菜,但却经常喜欢1v9。不过比起他...
  • ...这里使用ZXing生成二维码。直接上代码吧: package com.wjl.test; import java.awt.BasicStroke; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java....
  • 据我了解,网上一些生成二维码的类库,是没有直接生成带logo二维码的功能的。所以需要自己用代码在原二维码上绘制 logo,而用 java的awt绘制阴影???我是没听过。。。有哪位强迫症的大佬有想法弄这个阴影效果的...
  • 完整的项目,包括使用说明,logo图片等
  • 完美使用zxing生成二维码,可带logo,可解码,不仅如此,其中QRcode.java还可以用于生成二维码名片
  • Zxing 生成带logo二维码 下面放文字

    千次阅读 2018-08-21 17:43:12
    生成二维码图片:     package com.psd.utils; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.HashMap; import java....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,248
精华内容 899
关键字:

使用zxing生成带logo二维码