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.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import javax.imageio.ImageIO;
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;
public class QRCode
{
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
private static final int WIDTH = 30;
private static final int HEIGHT = 30;
private QRCode(){};
/**
* drawQrcode(创建二维码通用方法)
* @param matrix
* @param logoPath logo文件路径
* @Exception IOException
*/
public static BufferedImage drawQrcode(BitMatrix matrix, String logoPath) throws IOException
{
int width = matrix.getWidth();
int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE);
}
}
insertImage(image, logoPath, true);
return image;
}
/**
* drawQrcode(创建二维码通用方法)
* @param matrix
* @param logoPath logo文件路径
* @param needCompress 是否需要压缩logo
* @Exception IOException
*/
public static BufferedImage drawQrcode(BitMatrix matrix, String logoPath, boolean needCompress) throws IOException
{
int width = matrix.getWidth();
int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE);
}
}
insertImage(image, logoPath, needCompress);
return image;
}
/**
* drawQrcode(创建二维码通用方法)
* @param matrix
* @param logoPath logo文件路径
* @param format 文件格式
* @param file 生成的二维码文件
* @Exception IOException
*/
public static void writeToFile(BitMatrix matrix, String logoPath, String format, File file) throws IOException
{
BufferedImage image = drawQrcode(matrix, logoPath);
if(!ImageIO.write(image, format, file))
{
throw new IOException("could not write an image of format"+format+" to file"+file);
}
}
/**
* drawQrcode(创建二维码通用方法)
* @param matrix
* @param logoPath logo文件路径
* @param format 文件格式
* @param stream 生成的二维码文件流
* @Exception IOException
*/
public static void writeToStream(BitMatrix matrix, String logoPath, String format, OutputStream stream) throws IOException
{
BufferedImage image = drawQrcode(matrix, logoPath);
if(!ImageIO.write(image, format, stream))
{
throw new IOException("could not write an image of format"+format);
}
}
/**
* insertImage(向二维码中插入logo)
* @param image BufferedImage对象
* @param logoPath logo文件路径
* @param needCompress 是否需要压缩logo
*/
private static void insertImage(BufferedImage image, String logoPath, boolean needCompress) throws IOException
{
File file = new File(logoPath);
if(!file.exists())
{
System.err.println("该文件不存在"+logoPath);
}
Image src = ImageIO.read(file);
int width = src.getWidth(null);
int height = src.getHeight(null);
if(needCompress)
{
if(width > WIDTH)
{
width = WIDTH;
}
if(height > HEIGHT)
{
height = HEIGHT;
}
}
Image img = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
Graphics gs = bufImg.getGraphics();
gs.drawImage(img, 0, 0, null);
gs.dispose();
src = img;
Graphics2D gs2d = image.createGraphics();
int x = (image.getWidth() - width)/2;
int y = (image.getHeight() - height)/2;
gs2d.drawImage(src, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, height, 6, 6);
gs2d.setStroke(new BasicStroke(3f));
gs2d.draw(shape);
gs2d.dispose();
}
@SuppressWarnings("unchecked")
public static void main(String[] args) throws WriterException, IOException
{
String text = "然而《读者文摘》的发展并非一帆风顺。1982年初,美国《读者文摘》来函指出:甘肃人民出版社使用《读者文摘》中文" +
"名是不正当的,不符合国际版权协定。中美两家《读者文摘》长达数年的版权之争从此开始。从1990年开始,中美两家"+
"《读者文摘》的版权之争再次升级。1992年美国《读者文摘》委托律师致函中国《读者文摘》,要求停止使用中文商标《读者文摘》。" +
"后为化解与美国《读者文摘》发生的版权纠纷,1993年3月号《读者文摘》刊登征名启事,在读者中引起强烈反响,共收到应征信十万多封。" +
"信中提到新名有:读者、读友、读者之家、谈天说地、共享等等。最后使用了《读者》一名。1993年第七期,《读者文摘》正式改名为《读者》。";
int width = 300;
int height = 300;
String format = "jpg";
String logoPath = "G:/学习/桌面文件备份/123.jpg";
Hashtable table = new Hashtable();
table.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix matrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, table);
File file = new File("d:"+File.separator+"qrcode.jpg");
QRCode.writeToFile(matrix, logoPath, format, file);
}
}