二维码图片处理
将微信小程序的二维码图片中间加logo 和给图片加文字
获取二维码图片上一篇文章有讲到怎么获取
相关的pom
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
首先获取logo图片,我是发送远程请求获取的图片
// 首先获取log图片
HttpResponse httpResponse = HttpUtils.doGet(url);
InputStream content = httpResponse.getEntity().getContent();
//这里将logo转换成BufferImage 画布处理需要
BufferedImage logoImage = ImageIO.read(content);
//将logo压缩成指定大小
//绘制图像:返回一个新的按照with,height缩放呈现的Image
//这里的两百是你想将logo图片变化的大小
Image scaledInstance = logoImage .getScaledInstance(200, 200, Image.SCALE_SMOOTH);
// 构造一个新的BufferedImage 宽高200*200
logoImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
logoImage .getGraphics().drawImage(scaledInstance, 0, 0, null);
return logoImage ;//这里返回的是BufferImage
将正方形图片去掉角边
/*** 图片切圆角
*@paramsrc Image 方形logo图片
*@paramr adius radius 如果想为圆形 redius需等于log长度
*@return
*/
public static BufferedImage setClip(BufferedImage srcImage, int radius){
int width =srcImage.getWidth();
int height =srcImage.getHeight();
//新生成指定大小画布
BufferedImage image= new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D gs=image.createGraphics();
gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
gs.setClip(new RoundRectangle2D.Double(0, 0, width, height, radius, radius));
gs.drawImage(srcImage,0, 0, null);//将logo从新生成的画布原点开始画图
gs.dispose();//处理绘图
return image;
}
给二维码增加文字替换logo
//生成新的二维码 image 二维码
public BufferedImage createNewPic(String uGuid, BufferedImage image) throws IOException {
//获取二维码的宽高
int width = image.getWidth();
int height = image.getHeight();
//生成新的画布 这里是生成一个新的画布,放文字相对更美观 ,如果不需要也可以根据二维码生成新的画布,不过如果字体过大可能是会挡住部分二维码的
//画布的宽和二维码一样
int picWid=width;
int picHeight=height + 34;//因为字体我设置的16 所以高度相对增加一些
BufferedImage BufImage = new BufferedImage(picWid, picHeight, BufferedImage.TYPE_INT_RGB);// RGB形式
Graphics2D g = BufImage.createGraphics();
g.drawRect(0,0,picWid,picHeight);//画线框
g.setColor(Color.black);//将画布填充颜色
g.fillRect(0,0,picWid,picHeight);//是用预定的颜色填充一个矩形
g.drawImage(image, 0, 0, null);
// //基于二维码打开画布
// Graphics2D rng = image.createGraphics();
// rng.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP));
//获取设备名称编号 这里我是获取自己的文字信息
EMEquipmentEntity one = equipmentApi.getOneWithMapString("uGuid@EQ:" + uGuid);
String equipmentName = one.getEquipmentName();
String equipmentCode = one.getEquipmentCode();
String uClientId = SysContext.getClientId();
if (SysContext.getClientId() == null) uClientId = one.getuClientId();
String code = "设备名称:"+ equipmentName + " 设备编码:" + equipmentCode;
//这里是获取我存放图片的路径
EnterpriseLogEntity enterpriseLogEntity = enterpriseLogApi.getOneWithMapString("bUsable@EQ:true,uClientId@EQ:" + uClientId);
if (enterpriseLogEntity != null) {
String url = path + enterpriseLogEntity.getsLocalPath();
// 首先获取log图片
HttpResponse httpResponse = HttpUtils.doGet(url);
InputStream content = httpResponse.getEntity().getContent();
BufferedImage logoImage = ImageIO.read(content);
//计算中间图片的比例 根据二维码中图片的比例 如果二维码大小不一定放出来
// BufferedImage tag = handleImage(logoImage,f); 参数加个f,计算具体log的长宽
int width1 = logoImage.getWidth();
int height1 = logoImage.getHeight();
float f = (float) width1/(float) 200;
// ==================================
ByteArrayOutputStream bs = null;
ImageOutputStream imOut = null;
InputStream byteArrayInputStream = null;
try {
//处理图片生成新的BufferedImage 这里就是前面写的将logo图片压缩或放大的方法
BufferedImage tag = handleImage(logoImage);
bs = new ByteArrayOutputStream();
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(tag, "png", imOut);
byteArrayInputStream = new ByteArrayInputStream(bs.toByteArray());
} catch (IOException e) {
throw new IllegalArgumentException("compress image error:", e);
} finally {
//释放资源
close(bs, imOut);
}
BufferedImage read = ImageIO.read(byteArrayInputStream);
//去掉log图片的边角 200是中间替换图片的款度 log.宽度=200 参数radius给200 则为圆 参数200根据log的长宽改变
read = setClip(read,200);
//log的宽高
int logoWidth = read.getWidth();
int logoHeight = read.getHeight();
//log存在与二维码的位置
int x = (width-logoWidth)/2;
int y = (height-logoHeight)/2;
//定义log所在二维码得位置
g.drawImage(read, x, y, null);
}
//这里windows可以直接这么写,苹果系统需要导入相应的字体库
//Font.PLAIN(普通)
//Font.BOLD(加粗)
//Font.ITALIC(斜体)
//Font.BOLD+ Font.ITALIC(粗斜体)
Font font = new Font("楷体", Font.BOLD, 16);
g.setFont(font);
g.setColor(Color.white);
// 获取当前文字的对象
FontMetrics metrics1 = g.getFontMetrics(font);
//判断字体宽度,如果超过二维码大小就换行
if (metrics1.stringWidth(code) <= width) {
int startX1 = (width - metrics1.stringWidth(code)) / 2;
g.drawString(code, startX1, height+17);
} else {//这么做的个换行,因为我的不会超过两行如果你们的不止的话可以写个递归就可以解决了,但是不要忘了处理画布的高度
String[] split = StrUtil.split(code, code.length() / 2);
int startX1 = (width - metrics1.stringWidth(split[0])) / 2;
g.drawString(split[0].replace(" ",""), startX1, height+17);
g.drawString(split[1].replace(" ",""), startX1, height+34);
}
// 处理绘图
g.dispose();
BufImage.flush();
return BufImage;//这里就是处理好的二维码图片
//这是bufferImage类型的,要传给前端需要inputStream 上面logo处理那里有方法可以参考
}