Java 生成图片(图片合成二维码、文字)
package com.ssish.wxmall.common.data; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import javax.imageio.IIOImage; import javax.imageio.ImageIO; import javax.imageio.ImageWriter; import javax.imageio.plugins.jpeg.JPEGImageWriteParam; import javax.imageio.stream.ImageOutputStream; import org.apache.commons.lang3.StringUtils; /** * Java 图片生成 * * @author houzhenghai * @date 2018年10月19日 下午4:59:35 */ public class DrawingUtils { private static float jPEGcompression = 0.75f;// 图片清晰比率 /** * 图片制作 * @param backImage 背景图地址 * @param srcImage 二维码地址 * @param descImage //生成后的图片 * @param descImageLeft * @param descImageTop */ public static void makeImage(String backImage, String srcImage, String descImage, int descImageLeft,int descImageTop) { try { int offset = 0; BufferedImage backBufferedImage = ImageIO.read(new URL(backImage)); BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage)); // 输出图片宽度 int width = backBufferedImage.getWidth() + offset; // 输出图片高度 int height = backBufferedImage.getHeight() + offset; BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics(); graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 往画布上添加图片,并设置边距 graphics2d.drawImage(backBufferedImage, null, 0, 0); graphics2d.drawImage(srcBufferedImage, null, descImageLeft, descImageTop); graphics2d.dispose(); // 输出新图片 ImageIO.write(descBufferedImage, backImage.substring(backImage.lastIndexOf(".")+1, backImage.length()), new File(descImage)); } catch (Exception e) { e.printStackTrace(); } } /** * @Description : 将二维码图片和文字生成到一张图片上 * @Param : localFilePath 生成的新图片存放路径 * @Param : originalImg 原图 * @Param : qrCodeImg 二维码地址 * @Param : shareDesc 图片文字 * @return : java.lang.String * @Author : houzhenghai * @Date : 2018/8/15 */ public static ByteArrayOutputStream makeImage(String localFilePath,String originalImg, String qrCodeImg,int qrCodePaddingLeft,int qrCodePaddingTop,int qrCodeWidth,int qrCodeHeight,String shareDesc) throws Exception { /* // 加载原图图片 BufferedImage imageLocal = ImageIO.read(new URL(originalImg)); // 加载用户的二维码 BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg)); // 以原图片为模板 Graphics2D g = imageLocal.createGraphics(); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); g.setComposite(ac); g.setBackground(Color.WHITE); // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知) //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null); g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null); // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN, 40)); g.setColor(Color.red); // 计算文字长度,计算居中的x点坐标 //g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530); // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16)); g.setColor(Color.WHITE); // 计算文字长度,计算居中的x点坐标 String caewm = "长按二维码"; g.drawString(caewm, 105, imageLocal.getHeight() - 10); ByteArrayOutputStream out = new ByteArrayOutputStream(); */ // 加载原图图片 BufferedImage imageLocal = null; if(StringUtils.isNotBlank(originalImg)&&originalImg.toLowerCase().indexOf("http")!=-1) { imageLocal = ImageIO.read(new URL(originalImg)); }else { imageLocal = ImageIO.read(new File(originalImg)); } // 加载用户的二维码 BufferedImage imageCode = null; if(StringUtils.isNotBlank(qrCodeImg)&&qrCodeImg.toLowerCase().indexOf("http")!=-1) { imageCode = ImageIO.read(new URL(qrCodeImg)); }else { imageCode = ImageIO.read(new File(qrCodeImg)); } // 以原图片为模板 Graphics2D g = imageLocal.createGraphics(); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); g.setComposite(ac); g.setBackground(Color.WHITE); // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知) //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null); //g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null); //加载头像 http://image.ssish.com/uniFolder/476/userAvatar/0.png /*String headImg="http://image.ssish.com/uniFolder/476/userAvatar/0.png"; BufferedImage headCode = null; if(StringUtils.isNotBlank(headImg)&&headImg.toLowerCase().indexOf("http")!=-1) { headCode = ImageIO.read(new URL(headImg)); }else { headCode = ImageIO.read(new File(headImg)); } g.drawImage(headCode, 100, imageLocal.getHeight() - 100, 100, 100, null);*/ g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null); // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN, 40)); g.setColor(Color.red); // 计算文字长度,计算居中的x点坐标 g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530); // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16)); g.setColor(Color.WHITE); // 计算文字长度,计算居中的x点坐标 /* String caewm = "长按二维码"; g.drawString(caewm, 105, imageLocal.getHeight() - 10); */ ByteArrayOutputStream out = new ByteArrayOutputStream(); saveAsJPEG(imageLocal, out); //FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ; //out.writeTo(fileOutputStream) ; //fileOutputStream.flush(); //out.close(); //return urlImgDownInputStream(FileUtils.parse(out)); FileOutputStream fileOutputStream = new FileOutputStream( new File(localFilePath) ) ; out.writeTo(fileOutputStream) ; fileOutputStream.flush(); out.close(); return out; } /** * @Description : 将二维码图片和文字生成到一张图片上 * @Param : originalImg 原图 * @Param : qrCodeImg 二维码地址 * @Param : shareDesc 图片文字 * @return : java.lang.String * @Author : houzhenghai * @Date : 2018/8/15 */ public static String generateImg(String originalImg, String qrCodeImg, String shareDesc) throws Exception { // 加载原图图片 BufferedImage imageLocal = ImageIO.read(new URL(originalImg)); // 加载用户的二维码 BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg)); // 以原图片为模板 Graphics2D g = imageLocal.createGraphics(); AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP); g.setComposite(ac); g.setBackground(Color.WHITE); // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知) //g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null); //g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null); g.drawImage(imageCode, 760, imageLocal.getHeight() - 340, 300, 300, null); // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN, 40)); g.setColor(Color.red); // 计算文字长度,计算居中的x点坐标 /* g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530); */ // 设置文本样式 g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16)); g.setColor(Color.WHITE); // 计算文字长度,计算居中的x点坐标 /* String caewm = "长按二维码"; g.drawString(caewm, 105, imageLocal.getHeight() - 10); */ ByteArrayOutputStream out = new ByteArrayOutputStream(); saveAsJPEG(imageLocal, out); FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ; out.writeTo(fileOutputStream) ; fileOutputStream.flush(); out.close(); //return urlImgDownInputStream(FileUtils.parse(out)); return null; } public static void mergeImage(String backImage, String srcImage, String descImage) { try { int offset = 0; BufferedImage backBufferedImage = ImageIO.read(new URL(backImage)); BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage)); // 输出图片宽度 int width = backBufferedImage.getWidth() + offset; // 输出图片高度 int height = backBufferedImage.getHeight() + offset; BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics(); graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); // 往画布上添加图片,并设置边距 graphics2d.drawImage(backBufferedImage, null, 0, 0); graphics2d.drawImage(srcBufferedImage, null, 175, 175); graphics2d.dispose(); // 输出新图片 ImageIO.write(descBufferedImage, "png", new File(descImage)); } catch (Exception e) { e.printStackTrace(); } } /** * 以JPEG编码保存图片 * * @param image_to_save * 要处理的图像图片 * @param fos * 文件输出流 * @throws IOException */ private static void saveAsJPEG(BufferedImage imageToSave, ByteArrayOutputStream fos) throws IOException { ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next(); ImageOutputStream ios = ImageIO.createImageOutputStream(fos); imageWriter.setOutput(ios); if (jPEGcompression >= 0 && jPEGcompression <= 1f) { // new Compression JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam(); jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT); jpegParams.setCompressionQuality(jPEGcompression); } // new Write and clean up ImageIO.setUseCache(false); imageWriter.write(new IIOImage(imageToSave, null, null)); ios.close(); imageWriter.dispose(); } /** * 图片流远程上传 * * @author houzhenghai * @date 2018年10月19日 下午5:07:24 * @param inStream * @param imgType * @return * @throws Exception */ /* private static String urlImgDownInputStream(InputStream inStream) throws Exception { String md5 = MD5Utils.MD5(TimeUtils.getTimestamp().toString()); HttpClient httpclient = new DefaultHttpClient(); try { HttpPost post = new HttpPost(IMG_UPLOAD_PATH);// 文件服务器上传图片地址 MultipartEntity mpEntity = new MultipartEntity(); ContentBody contb = new InputStreamBody(inStream, md5 + ".png"); mpEntity.addPart("Filedata", contb); post.setEntity(mpEntity); HttpResponse httpResponse = httpclient.execute(post); HttpEntity entity = httpResponse.getEntity(); String jsonStr = EntityUtils.toString(entity); JSONObject ob = JSONObject.fromObject(jsonStr); if (!ob.isEmpty() && ob.containsKey("pic_id")) { return ob.getString("pic_id"); } } catch (Exception e) { e.printStackTrace(); } finally { httpclient.getConnectionManager().shutdown(); } return null; } */ /** * test * * @param args * @throws */ /* public static void main(String[] args) { long starttime = System.currentTimeMillis(); System.out.println("开始:" + starttime); try { String originalImg = "http://image.run4wd.com/newBee/invitationposter/821806.jpg"; String qrCodeImg = "http://image.run4wd.com/newBee/invitationposter/qrcode/612278_qrcode.jpg"; String shareDesc = ""; String img = generateImg(originalImg, qrCodeImg, shareDesc); System.out.println("生成完毕,url=" + img); } catch (Exception e) { e.printStackTrace(); } System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000); } */ public static void main(String[] args) { long starttime = System.currentTimeMillis(); System.out.println("开始:" + starttime); /* //两张图片合成一张 try { String originalImg = "http://image.ssish.com/newBee/poster/invitation/765029.jpg"; String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg"; String shareDesc = "d:/33.png"; makeImage(originalImg, qrCodeImg, shareDesc,760,1389); //System.out.println("生成完毕,url=" + img); } catch (Exception e) { e.printStackTrace(); } */ //两张图片合成一张并加文字 String[] posterInvitationPositionParamArr = "280,280,760,345,280,280".split(","); //String localFilePath="/datavg/temp/newimg.png";//生成的新图片放在临时目录下 String localFilePath="d:/test.jpg";//生成的新图片放在临时目录下 String originalImg = "http://image.ssish.com/newBee/poster/invitation/823941.jpg"; String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg"; try { ByteArrayOutputStream os=DrawingUtils.makeImage(localFilePath,originalImg, qrCodeImg, Integer.valueOf(posterInvitationPositionParamArr[2]), Integer.valueOf(posterInvitationPositionParamArr[3]), Integer.valueOf(posterInvitationPositionParamArr[4]), Integer.valueOf(posterInvitationPositionParamArr[5]), "张三,欢迎你!"); } catch (Exception e) { e.printStackTrace(); } //把生成的新图片上传到服务器,并删除临时目录下的文件 /*String fileName=localFilePath.substring(localFilePath.lastIndexOf("/")+1,localFilePath.length()); ossService.upload(new File(localFilePath),"poster/invitation/"+fileName); FileUtils.deleteFile(localFilePath);*/ System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000); } }
合成后的新图片