java生成带logo的二维码,自定义大小,logo路径取服务器端

package com.qishunet.eaehweb.util;

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.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.imageio.ImageIO;

import net.sf.cglib.core.CollectionUtils;

import org.apache.tiles.request.collection.CollectionUtil;

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;

public class QRCodeUtil {
    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static int QRCODE_SIZE = 132;
    // LOGO宽度
    private static int WIDTH = 34;
    // LOGO高度
    private static int HEIGHT = 34;

    private static BufferedImage createImage(String content, String imgPath,
            boolean needCompress) throws Exception {
        Hashtable hints = new Hashtable();
        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;
        }
        // 插入图片
        QRCodeUtil.insertImage(image, imgPath, needCompress);
        return image;
    }

    private static void insertImage(BufferedImage source, String imgPath,
            boolean needCompress) throws Exception {
        URL url = null;
        HttpURLConnection httpUrl = null;
        try {
             url = new URL(imgPath);
             httpUrl = (HttpURLConnection) url.openConnection();
        } catch (Exception e) {
            System.out.println(""+imgPath+"打开logo连接失败");
        }
        Image src = ImageIO.read(httpUrl.getInputStream());
        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();
    }

   /**
    *
    * @param content  url
    * @param imgPath  logo图片的路径
    * @param userid  用户id
    * @param map  二维码大小参数
    * @param needCompress  是否压缩
    * @return
    * @throws Exception
    */
    public static String  encode(String content, String imgPath,Long userid,Map<String,Integer> map,boolean needCompress) throws Exception {

        String path = SystemPropertiesUtil.get("uploadIp");

        String uploadPath = SystemPropertiesUtil.get("uploadPath");

        String suploadPath = "/userImg/"+ (userid % 10) + "/"+ userid + "/";

        String uploadpath = uploadPath + suploadPath;

        String fileName = "qrCode" + userid + ".png";

        File file = new File(uploadpath + fileName);

        if (file.exists()) {
            return path + suploadPath + fileName;
        }

        if (!map.isEmpty()){
            if (map.containsKey("size")){
                QRCODE_SIZE = map.get("size");
            }
            if (map.containsKey("width")){
                WIDTH = map.get("width");
            }
            if (map.containsKey("size")){
                HEIGHT = map.get("height");
            }
        }
        try {
           BufferedImage image = QRCodeUtil.createImage(content, imgPath,needCompress);
           mkdirs(uploadpath);
           ImageIO.write(image, FORMAT_NAME, new File(""+file));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return path + suploadPath + fileName;
    }

    public static void mkdirs(String destPath) {
        File file =new File(destPath);
        //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
    }

    public static void encode(String content, String imgPath,
            OutputStream output, boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtil.createImage(content, imgPath,
                needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }

    public static void encode(String content, OutputStream output)
            throws Exception {
        QRCodeUtil.encode(content, null, output, false);
    }

    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 hints = new Hashtable();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        String resultStr = result.getText();
        return resultStr;
    }

    public static String decode(String path) throws Exception {
        return QRCodeUtil.decode(new File(path));
    }

    public static void main(String[] args) throws Exception {
        String text = "http://www.dans88.com.cn";
        //QRCodeUtil.encode(text, "d:/MyWorkDoc/my180.jpg", "d:/MyWorkDoc", true);
    }
}
package com.qishunet.eaehweb.util;

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);
    }
}
时间: 2024-12-25 16:00:15

java生成带logo的二维码,自定义大小,logo路径取服务器端的相关文章

Java生成带小图标的二维码-google zxing 工具类

近期一直忙于开发微信商城项目,应客户要求,要开发个有图标的二维码.经过两次改版,终于实现了该功能(第一次没有小图标,这次才整合好的),如下是完整代码 . 该代码使用Java7开发,另外使用 core-2.2.jar jar[http://pan.baidu.com/s/1skTwHQ1] 包 . 1 package com.rick.common.utils; 2 3 4 import java.awt.Color; 5 import java.awt.Graphics2D; 6 import

Java使用zpxing.jar生成带url的二维码

第一步下载zpxing.jar包,并加载进来(网上有很多类似的jar包,这里小编使用的是谷歌提供的jar) 二维码工具类: package com.zpxing.controller; import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Shape; import java.awt.geom.RoundRe

微信公众号开发(三)生成带参数的二维码

微信公众号开发之生成带参数的二维码 做微信公众号开发的人员都知道用户海报作为公众号吸引用户是常见的渠道,那么我就说说这个海报的生成. 看了好多公众号发现他们的海报都是大同小异,一个漂亮的背景+自己的头像+专属二维码. 背景就不阐述了,用户的头像可以由公众号开发文档提供的方式获取(根据用户的openId),今天主要讲用户的专属二维码 所谓专属即便是一对一的. 二维码分为两种,临时二维码和永久二维码 /*生成永久二维码*/ public static String getPerpetualQR(St

微信公众平台功能开发(生成带参数的二维码)

为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送. 目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--100000).两种二维码分别适用于帐号绑定.用户来源统计等场景. 用户扫描带场景值二维码时,可能推送以下两种事件: 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事

C#微信开发之旅(六):生成带参数的二维码

主要用来推广并统计数据,当用户扫描带参数二维码时,微信会推送消息到我们的服务器,此时可以根据参数了解到用户是从哪个渠道关注的.话不多少,先来代码: 1 #region 生成二维码 2 3 /// <summary> 4 /// 获取Ticket 5 /// </summary> 6 /// <returns></returns> 7 private static string CreateTicket(string scene_id) 8 { 9 var t

微信接口开发之高级篇系列【用户分组接口和生成带参数的二维码】

<?php /** * Created by PhpStorm. * User: Tinywan * Date: 2016/9/11 * Time: 10:00 */ namespace Home\Controller; use Org\Util\WechatAuth; use Think\Controller; class UserController extends Controller { private $appid; private $appSecret; private $Wecha

生成带参数的二维码

为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送. 目前有2种类型的二维码,分别是临时二维码和永久二维码,前者有过期时间,最大为1800秒,但能够生成较多数量,后者无过期时间,数量较少(目前参数只支持1--100000).两种二维码分别适用于帐号绑定.用户来源统计等场景. 用户扫描带场景值二维码时,可能推送以下两种事件: 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事

微信公众平台 怎样生成带参数的二维码

添加带参数二维码 1.选择要添加带参数二维码的认证服务号--功能管理--高级功能--渠道二维码生成--+创建渠道二维码 1.1.渠道名称:可以理解为一个推广员(门店)一个渠道的名称: 1.2.触发关键词:即粉丝扫描这个二维码后直接弹出的回复内容,可以多个渠道共用一个关键词,也可以每个渠道用一个关键词: 1.3.扫码统计对象:可以统计新.老粉丝的关注取消数据: 1.4.粉丝识别标识:打标签及分组: 1.5.保存:添加好渠道名称和触发关键词就会直接生成这个渠道的二维码,直接点击[获取二维码]即可得到

微信开发之——Php批量生成带参数的二维码

带参数的二维码对于渠道营销推广来说是很有用的,可以获得多个带不同场景值的二维码,用户扫描后,公众号可以接收到事件推送,可喜的是微信开通了这个接口,那下面就来研究一下吧. 具体接口说明请参见,微信公众平台开发者文档(http://mp.weixin.qq.com/wiki/18/28fc21e7ed87bec960651f0ce873ef8a.html),我这里就直接上代码. 演示图: 由于带参数二维码生成是有限的,所有我是按编号生成的,下次生成的时候直接累加. 另外带设置有备注,方便以后统计.

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

效果图如下: 制作过程很简单的就是在原始的二维码图片上添加一个logn图标,代码的注释写得很详细,也就不给大家啰嗦了 package com.example.day44_02_qrcodewithlogin; import java.util.HashMap; import java.util.Map; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Bitmap.Confi