Java生成二维码以及java绘图
前言
Github:https://github.com/HealerJean
项目中用到了生成二维码以及通过二维码制作为推广图片,如下,(用到了log,将logo放到了二维码中间)二维码和推广图片
logo
二维码
推广图片
好了不废话了,开始制作,首先我们是要下载这个图片的
主要学习:BufferedImage
//整体图合成
BufferedImage bufferedImage = new BufferedImage(lovelyImageWidth, lovelyImageHeight, BufferedImage.TYPE_INT_RGB);
//设置图片的背景色
Graphics2D main = bufferedImage.createGraphics();
main.fillRect(0, 0, lovelyImageWidth, lovelyImageHeight);
制作好的图片写入输出流
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
网络图片获取
URL u = new URL(couponExpireChange.getImgUrl());
BufferedImage imageQR = ImageIO.read(u);
为文件中写入
FileOutputStream outputStreamContactmanager = new FileOutputStream(contactmanager);
URL ucontactmanager = new URL("http://image.dangqugame.cn/admin/webproject/contactmanager.jpg");
BufferedImage imageContactmanager = ImageIO.read(ucontactmanager);
ImageIO.write(imageContactmanager, "jpg", outputStreamContactmanager);
1、controlelr
@ApiOperation(value = "下载优惠券二维码",notes = "下载优惠券二维码",
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
@ApiImplicitParams({
@ApiImplicitParam(name="couponItemGoodId",value = "优惠券商品主键Id",required = true,dataTypeClass = Long.class,paramType = "query")
})
@GetMapping("downQcode")
public void downQcode(Long couponItemGoodId,HttpServletRequest request, HttpServletResponse response){
log.debug("the imageName is : "+couponItemGoodId);
//设置文件路径
response.setContentType("application/force-download");// 设置强制下载不打开
response.addHeader("Content-Disposition", "attachment;fileName="+UUIDGenerator.generate() +"jpg");// 设置文件名
qrCodeService.downLoadErWeiMa(response,couponItemGoodId);
}
2、service中开始
/**
* 优惠券商品二维码制作输出流
* @param response
* @param couponItemGoodId
* @return
*/
public OutputStream downLoadErWeiMa(HttpServletResponse response, Long couponItemGoodId){
if(couponItemGoodId==null){
throw new AppException("couponItemGoodId为空");
}
CouponItemGood couponItemGood = couponItemGoodRepository.findOne(couponItemGoodId);
CouponItemGood couponItemGoodFinal = couponItemGood;
if(couponItemGood==null){
throw new AppException("couponItemGoodId未找到对应主键的优惠券商品");
}
//我们后台自动匹配生成的,以及 失效后没有匹配的
if(couponItemGood.getConnectParentItemGoodId()!=null||(couponItemGood.getStatus().compareTo(EnumValid.无效.status)==0&&couponItemGood.getConnectItemGoodId()==null)){
throw new AppException("该优惠券无效或找不到匹配的优惠券");
}
//未进入转链接的进入转链接
CouponExpireChange couponExpireChange = null ;
if(couponItemGood.getQCodeIs().compareTo(EnumQcodeUse.未使用.status)==0){
changeLinkService.addCouponExpireChange(Long.valueOf(couponItemGoodId));
}else {//已经在使用了
if(couponItemGood.getConnectParentItemGoodId()!=null){
couponExpireChange = couponExpireChangeRepository.findByPastItemGoodId(couponItemGood.getConnectParentItemGoodId());
couponItemGoodFinal = couponItemGoodRepository.findOne(couponItemGood.getConnectParentItemGoodId());
}else{
couponExpireChange = couponExpireChangeRepository.findByPastItemGoodId(couponItemGoodId);
}
}
WechatUrl wechatUrl = wechatUrlRepository.findByStatusIs(EnumValid.有效.status);
OutputStream outputStream =null;
if(couponExpireChange!=null){ //已经是二维码了
try {
//需要添加的图片(二维码中间的图片必须有)
URL u = new URL(couponExpireChange.getImgUrl());
BufferedImage imageQR = ImageIO.read(u);
//需要添加的图片
// String imageQRUrl = "/Users/healerjean/Desktop/images/itemgood.jpeg";
// FileInputStream inputStream = new FileInputStream(imageQRUrl);
// BufferedImage imageQR = ImageIO.read(inputStream);
BufferedImage ErWeiMaImage = QRCodeUtils.writeQRImg(response,wechatUrl.getUrl()+couponExpireChange.getPastItemGoodId(), WeChatMessageParams.WECHAT_DUODIANYOUHUI_LOGO);
String titleLab = "包邮";
String title = couponItemGoodFinal.getTitle();
BigDecimal originPrice = couponItemGoodFinal.getOriginPrice();
BigDecimal nowPrice =couponItemGoodFinal.getNowPrice();
BigDecimal couponPrice =couponItemGoodFinal.getCouponPrice();
String description = couponItemGoodFinal.getItemDescription();
BufferedImage bufferedImage =ChartGraphics. graphicsGenerationlovely(imageQR, ErWeiMaImage,titleLab,title,originPrice,nowPrice,couponPrice,description);
ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
return outputStream;
//获取二维码图片,下面开始整合资源
} catch (Exception e) {
log.info(e.getMessage());
}
}
return outputStream;
}
2.1、生成二维码
package com.duodian.youhui.admin.utils.qCode;
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.springframework.web.bind.annotation.RequestAttribute;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.UUID;
public class QRCodeUtils {
// 二维码宽度
private static Integer WIDTH_PIX = 300;
// 二维码高度
private static Integer HEIGHT_PIX = 300;
// 生成文件类型
private static String TYPE = "jpg";
// 编码格式
private static String CHAR_TYPE = "UTF-8";
/** 二维码填充颜色 BEGIN*/
// 黑色
private static Integer COLOR_BLACK = 0XFF000000;
// 白色 0xFF是补码
private static Integer COLOR_WHITE = 0XFFFFFFFF;
/** 二维码填充颜色 END*/
/**字体设定 BEGIN*/
//设定写在二维码上的字体 样式
private static String FONT_NAME = "Consolas";
//字体颜色
private static Color FONT_COLOR = Color.gray;
//字体 大小
private static Integer FONT_SIZE =12;
/**字体设定 END*/
/**
* 通过BufferedImage 来写入图片的操作,没有用到Google 的j2se包
*
* @param text
* 写入的信息
* 输出的文件地址
* @return
* @throws Exception
*/
public static BufferedImage writeQRImg(HttpServletResponse response,String text, String... logoPath) throws Exception {
// 配置参数
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 字符编码
hints.put(EncodeHintType.CHARACTER_SET, CHAR_TYPE);
// 容错级别
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 设置空白边距的宽度
hints.put(EncodeHintType.MARGIN, 3); // 默认是4
// 1、生成二维码
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, WIDTH_PIX, HEIGHT_PIX, hints);
// 2、获取二维码宽高
int codeWidth = bitMatrix.getWidth();
int codeHeight = bitMatrix.getHeight();
// 3、将二维码放入缓冲流
BufferedImage image = new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < codeWidth; i++) {
for (int j = 0; j < codeHeight; j++) {
// 4、循环将二维码内容定入图片
//判断 BitMatrix 是否存在像素
image.setRGB(i, j, bitMatrix.get(i, j) ? COLOR_BLACK : COLOR_WHITE);
}
}
//判断是否写入logo图片
if(logoPath != null && logoPath.length>0){
File logoPic = new File(logoPath[0]);
if (logoPic.exists()) {
//在原来基础上,再添加一个图片
Graphics2D g = image.createGraphics();
BufferedImage logo = ImageIO.read(logoPic);
int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ?
(image.getWidth() * 2 / 10) : logo.getWidth(null);
int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ?
(image.getHeight() * 2 / 10) : logo.getHeight(null);
//设定在图片中间
int x = (image.getWidth() - widthLogo) / 2;
int y = (image.getHeight() - heightLogo) / 2;
// 开始绘制图片
g.drawImage(logo, x, y, widthLogo, heightLogo, null);
//绘制圆角矩形
g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
//边框宽度
g.setStroke(new BasicStroke(2));
//边框颜色
g.setColor(Color.WHITE);
g.drawRect(x, y, widthLogo, heightLogo);
//最后一个参数用来设置字体的大小
Font fontStyle = new Font(FONT_NAME,Font.PLAIN,FONT_SIZE);
//设定颜色
g.setColor(FONT_COLOR); //设定颜色
g.setFont(fontStyle); //设定字体
Integer fontStartIndex = image.getWidth()-(int) (text.length()*FONT_SIZE*0.7);
g.drawString(text,fontStartIndex,image.getHeight()-FONT_SIZE);
//释放图像资源
g.dispose();
logo.flush();
image.flush();
}
}
return image;
}
//
//
// public static void main(String[] args) throws Exception {
// String logoPath = "/Users/healerjean/Desktop/images/duodianyouhuilogo.png";
// String outPath = "/Users/healerjean/Desktop";
// HttpServletResponse response = null;
// OutputStream outputStream= QRCodeUtils.writeQRImg(response,"http://test.dangqugame.cn/duodian/youhui/redirectTaoKouLing?taokouling=¥3hxo0EfH68X¥", outPath,logoPath);
// }
}
2.2、将二维码和图片进行合成
package com.duodian.youhui.admin.utils.qCode;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
public class ChartGraphics {
public static List<String> getStrList(String inputString, int length) {
int size = inputString.length() / length;
if (inputString.length() % length != 0) {
size += 1;
}
return getStrList(inputString, length, size);
}
public static List<String> getStrList(String inputString, int length,
int size) {
List<String> list = new ArrayList<String>();
for (int index = 0; index < size; index++) {
String childStr = substring(inputString, index * length,
(index + 1) * length);
list.add(childStr);
}
return list;
}
public static String substring(String str, int f, int t) {
if (f > str.length())
return null;
if (t > str.length()) {
return str.substring(f, str.length());
} else {
return str.substring(f, t);
}
}
public static BufferedImage graphicsGenerationlovely(BufferedImage imageQR, BufferedImage ImageerWeiMa,
String titleLab,
String title ,
BigDecimal originPrice ,
BigDecimal nowPrice ,
BigDecimal couponPrice ,
String description
) {
//整体图的高度和宽度
int lovelyImageWidth = 900;
int lovelyImageHeight = 1428;
//整体图合成
BufferedImage bufferedImage = new BufferedImage(lovelyImageWidth, lovelyImageHeight, BufferedImage.TYPE_INT_RGB);
//设置图片的背景色
Graphics2D main = bufferedImage.createGraphics();
main.fillRect(0, 0, lovelyImageWidth, lovelyImageHeight);
Graphics graphicsQR = bufferedImage.getGraphics();
graphicsQR.drawImage(imageQR, 0, 0, 900, 940, null);
graphicsQR.drawImage(ImageerWeiMa, 591, 992, 249, 249, null);
Graphics2D baoyou = bufferedImage.createGraphics();
baoyou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
baoyou.setColor(new Color(218, 83, 80));
baoyou.fillRect(25,985,60,30);
//固定文字 包邮
Graphics2D fixBaoyou = bufferedImage.createGraphics();
fixBaoyou.setColor(new Color(252, 250, 253));
Font baoyouFont = new Font("黑体", Font.PLAIN, 26);
fixBaoyou.setFont(baoyouFont);
fixBaoyou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixBaoyou.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String baoyouWenzi = titleLab;
fixBaoyou.drawString(baoyouWenzi, 25, 1010);
//固定文字 title
Graphics2D fixed = bufferedImage.createGraphics();
fixed.setColor(new Color(51, 51, 51));
Font fixedFont = new Font("黑体", Font.PLAIN, 37);
fixed.setFont(fixedFont);
//失真处理
fixed.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixed.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
List<String> list = getStrList(title,14);
int i = 1 ;
for(String str:list){
if(i==1){
fixed.drawString(str, 95, 1010);
}else if(i==2){
fixed.drawString(str, 20, 1055);
}else if(i ==3){
fixed.drawString(str, 20, 1095);
}
i++;
}
//固定文字 现价
Graphics2D fixNowPrice = bufferedImage.createGraphics();
fixNowPrice.setColor(new Color(51, 51, 51));
Font fixNowPriceFont = new Font("黑体", Font.PLAIN, 28);
fixNowPrice.setFont(fixNowPriceFont);
//失真处理
fixNowPrice.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixNowPrice.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String newPrice = "现价:¥"+originPrice;
fixNowPrice.drawString(newPrice, 25, 1166);
Graphics2D quanJx = bufferedImage.createGraphics();
quanJx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
quanJx.setColor(new Color(218, 83, 80));
quanJx.fillRect(25,1190,30,30);
//固定文字 券
Graphics2D fixquanWenzi = bufferedImage.createGraphics();
fixquanWenzi.setColor(new Color(252, 250, 253));
Font fixQuanHouwenziFont = new Font("黑体", Font.PLAIN, 26);
fixquanWenzi.setFont(fixQuanHouwenziFont);
//失真处理
fixquanWenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixquanWenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String quanwezi = "券";
fixquanWenzi.drawString(quanwezi, 25, 1215);
Graphics2D yuanJx = bufferedImage.createGraphics();
yuanJx.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
yuanJx.setColor(new Color(218, 83, 80));
yuanJx.drawRect(55,1190,60,30);
//固定文字 券
Graphics2D fixyuanWenzi = bufferedImage.createGraphics();
fixyuanWenzi.setColor(new Color(218, 83, 80));
Font fixyuanWenziFont = new Font("黑体", Font.PLAIN, 26);
fixyuanWenzi.setFont(fixyuanWenziFont);
//失真处理
fixyuanWenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixyuanWenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String yuan = couponPrice+"";
fixyuanWenzi.drawString(yuan, 55, 1215);
//固定文字 券以及券后价
Graphics2D fixQuanHou = bufferedImage.createGraphics();
fixQuanHou.setColor(new Color(51, 51, 51));
Font fixQuanHouFont = new Font("黑体", Font.PLAIN, 26);
fixQuanHou.setFont(fixQuanHouFont);
//失真处理
fixQuanHou.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixQuanHou.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String quanhoujia = "券后价:";
fixQuanHou.drawString(quanhoujia, 131, 1215);
//固定文字¥
Graphics2D meiyuan = bufferedImage.createGraphics();
meiyuan.setColor(new Color(218, 83, 80));
Font qhjPriceMeiyuanFont = new Font("黑体", Font.PLAIN, 30);
meiyuan.setFont(qhjPriceMeiyuanFont);
//失真处理
meiyuan.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
meiyuan.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String meiyuanWenZi = "¥";
meiyuan.drawString(meiyuanWenZi, 224, 1215);
//固定文字 9.90
Graphics2D qhjPrice = bufferedImage.createGraphics();
qhjPrice.setColor(new Color(218, 83, 80));
Font qhjPriceFont = new Font("黑体", Font.PLAIN, 60);
qhjPrice.setFont(qhjPriceFont);
//失真处理
qhjPrice.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
qhjPrice.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String QaunPrice = nowPrice+"";
qhjPrice.drawString(QaunPrice, 245, 1215);
Graphics2D sptjRect = bufferedImage.createGraphics();
sptjRect.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
sptjRect.setColor(new Color(218, 83, 80));
sptjRect.fillRect(25,1275,110,30);
//固定文字
Graphics2D fixsptjwenzi = bufferedImage.createGraphics();
fixsptjwenzi.setColor(new Color(252, 250, 253));
Font sptjFont = new Font("黑体", Font.PLAIN, 26);
fixsptjwenzi.setFont(sptjFont);
fixsptjwenzi.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixsptjwenzi.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String sptjwenzi = "商品推荐";
fixsptjwenzi.drawString(sptjwenzi, 25, 1300);
//商品推荐
Graphics2D fixTuiJian = bufferedImage.createGraphics();
fixTuiJian.setColor(new Color(51, 51, 51));
Font fixTuiJianFont = new Font("黑体", Font.PLAIN, 30);
fixTuiJian.setFont(fixTuiJianFont);
//失真处理
fixTuiJian.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
fixTuiJian.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
String tuijian = description;
List<String> tuijianList = getStrList(tuijian,24);
int m = 1 ;
for(String str:tuijianList){
if(m ==1){
fixTuiJian.drawString(str, 150, 1300);
}else if(m ==2){
fixTuiJian.drawString(str, 20, 1345);
}else if(m ==3){
fixTuiJian.drawString(str, 20, 1390);
}
m++;
}
return bufferedImage;
}
}
普通java绘图
https://blog.csdn.net/xietansheng/article/details/55669157
https://www.jb51.net/article/73136.htm