1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 图片合成工具类

图片合成工具类

时间:2020-03-14 07:13:37

相关推荐

图片合成工具类

工具类

package com.shuidihuzhu.razor.client.utils;import lombok.extern.slf4j.Slf4j;import javax.imageio.ImageIO;import java.awt.*;import java.awt.geom.AffineTransform;import java.awt.geom.Ellipse2D;import java.awt.geom.RoundRectangle2D;import java.awt.image.BufferedImage;import java.awt.image.ColorModel;import java.awt.image.WritableRaster;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import .URL;/*** * @date /2/3* 合成图片**/@Slf4jpublic class MergeImgUtil {/*** @param bigPath 背景图* @param smallPath 小图* @param x 宽多少像素* @param y 高多少像素*/public static void mergeImage(String bigPath, String smallPath, int x, int y) {try {BufferedImage small = getBufferedImage(smallPath);BufferedImage big = getBufferedImage(bigPath);Graphics2D g = big.createGraphics();g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);g.dispose();ImageIO.write(big, "png", new File(bigPath));} catch (Exception e) {e.printStackTrace();}}/*** @param bigPath* @param inputStream* @param x* @param y* @throws IOException*/public static void mergeImage(String bigPath, InputStream inputStream, int x, int y) {try {BufferedImage small = getBufferedImage(inputStream);BufferedImage big = getBufferedImage(bigPath);Graphics2D g = big.createGraphics();g.drawImage(small, x, y, small.getWidth(), small.getHeight(), null);g.dispose();ImageIO.write(big, "jpg", new File(bigPath));} catch (Exception e) {e.printStackTrace();}}private static BufferedImage getBufferedImage(String path) {BufferedImage img = null;try {String http = "http";if (path.contains(http)) {URL url = new URL(path);img = ImageIO.read(url);} else {img = ImageIO.read(new File(path));}} catch (IOException e) {log.error("获取图片失败");}return img;}private static BufferedImage getBufferedImage(InputStream inputStream) {BufferedImage img = null;try {img = ImageIO.read(inputStream);} catch (IOException e) {log.error("获取图片失败");}return img;}/*** 把指定头像切成圆形输出** @param srcImgPath 原头像* @param tarImgPath 圆形头像* @param x要切成大小 坐标 X 宽多少像素* @param y要切成大小 坐标 Y 高多少像素*/private static void imageToCircular(String srcImgPath, String tarImgPath, int x, int y) throws IOException {BufferedImage bi1 = ImageIO.read(new File(srcImgPath));// 根据需要是否使用 BufferedImage.TYPE_INT_ARGBBufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(),BufferedImage.TYPE_INT_RGB);Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight());Graphics2D g2 = bi2.createGraphics();g2.setBackground(Color.WHITE);g2.fill(new Rectangle(bi2.getWidth(), bi2.getHeight()));g2.setClip(shape);// 使用 setRenderingHint 设置抗锯齿g2.drawImage(bi1, 0, 0, null);g2.dispose();ImageIO.write(bi2, "png", new File(tarImgPath));}/*** @param srcImgPath 源图片路径* @param tarImgPath 保存的图片路径* @param waterMarkContent 水印内容* @param x坐标 X 宽多少像素* @param y坐标 Y 高多少像素* @param R RGB 数字 R* @param G RGB 数字 G* @param B RGB 数字 B* @param frontSize 文字大小*/public static void addWaterMark(String srcImgPath, String tarImgPath, String waterMarkContent, int x, int y,int R,int G,int B,int A,int frontSize) throws IOException {// 读取原图片信息得到文件File srcImgFile = new File(srcImgPath);文件转化为图片Image srcImg = ImageIO.read(srcImgFile);获取图片的宽int srcImgWidth = srcImg.getWidth(null);//获取图片的高int srcImgHeight = srcImg.getHeight(null);// 加水印BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g = bufImg.createGraphics();g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);根据图片的背景设置水印颜色Color color = new Color(R, G, B, A);//水印图片色彩以及透明度g.setColor(color);设置字体水印字体Font font = new Font("微软雅黑", Font.PLAIN, frontSize);g.setFont(font);//设置水印的坐标// int x = srcImgWidth - 2 * getWatermarkLength(waterMarkContent, g);// int y = srcImgHeight - 2 * getWatermarkLength(waterMarkContent, g);画出水印g.drawString(waterMarkContent, x, y);g.dispose();// 输出图片FileOutputStream outImgStream = new FileOutputStream(tarImgPath);ImageIO.write(bufImg, "png", outImgStream);log.debug("添加水印完成");outImgStream.flush();outImgStream.close();}public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());}/***** @param srcFilePath 源图片文件路径* @param circularImgSavePath 新生成的图片的保存路径,需要带有保存的文件名和后缀* @param targetSize 文件的边长,单位:像素,最终得到的是一张正方形的图,所以要求targetSize<=源文件的最小边长* @param cornerRadius 圆角半径,单位:像素。如果=targetSize那么得到的是圆形图* @return 文件的保存路径* @throws IOException*/public static String makeCircularImg(String srcFilePath, String circularImgSavePath, int targetSize, int cornerRadius) throws IOException {BufferedImage bufferedImage = ImageIO.read(new File(srcFilePath));BufferedImage circularBufferImage = roundImage(bufferedImage, targetSize, cornerRadius);ImageIO.write(circularBufferImage, "png", new File(circularImgSavePath));return circularImgSavePath;}private static BufferedImage roundImage(BufferedImage image, int targetSize, int cornerRadius) {BufferedImage outputImage = new BufferedImage(targetSize, targetSize, BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = outputImage.createGraphics();g2.setComposite(AlphaComposite.Src);g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2.setColor(Color.WHITE);g2.fill(new RoundRectangle2D.Float(0, 0, targetSize, targetSize, cornerRadius, cornerRadius));g2.setComposite(AlphaComposite.SrcAtop);g2.drawImage(image, 0, 0, null);g2.dispose();return outputImage;}/*** 生成圆角图标* @param image 图片路径* @param cornerRadius 圆角半径 720正圆形| 40是圆角形* @return*/public static BufferedImage makeRoundedCorner1(BufferedImage image, int cornerRadius) {BufferedImage output = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);Graphics2D g2 = output.createGraphics();g2.setComposite(AlphaComposite.Src);g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2.setColor(Color.WHITE);g2.fill(new RoundRectangle2D.Float(0, 0, image.getWidth(), image.getHeight(), cornerRadius, cornerRadius));g2.setComposite(AlphaComposite.SrcAtop);g2.drawImage(image, 0, 0, null);g2.dispose();return output;}/*** @param srcImg原图片* @param destImg 目标位置* @param width期望宽* @param height期望高* @param equalScale 是否等比例缩放*/public static void reSize(File srcImg, File destImg, int width,int height, boolean equalScale) {String type = getImageType(srcImg);if (type == null) {return;}if (width < 0 || height < 0) {return;}BufferedImage srcImage = null;try {srcImage = ImageIO.read(srcImg);System.out.println("srcImg size=" + srcImage.getWidth() + "X" + srcImage.getHeight());} catch (IOException e) {e.printStackTrace();return;}if (srcImage != null) {// targetW,targetH分别表示目标长和宽BufferedImage target = null;double sx = (double) width / srcImage.getWidth();double sy = (double) height / srcImage.getHeight();// 等比缩放if (equalScale) {if (sx > sy) {sx = sy;width = (int) (sx * srcImage.getWidth());} else {sy = sx;height = (int) (sy * srcImage.getHeight());}}System.out.println("destImg size=" + width + "X" + height);ColorModel cm = srcImage.getColorModel();WritableRaster raster = cm.createCompatibleWritableRaster(width, height);boolean alphaPremultiplied = cm.isAlphaPremultiplied();target = new BufferedImage(cm, raster, alphaPremultiplied, null);Graphics2D g = target.createGraphics();// smoother than exlax:g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);g.drawRenderedImage(srcImage, AffineTransform.getScaleInstance(sx, sy));g.dispose();// 将转换后的图片保存try {ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(target, type, baos);FileOutputStream fos = new FileOutputStream(destImg);fos.write(baos.toByteArray());fos.flush();fos.close();} catch (IOException e) {e.printStackTrace();}}}/*** 获取文件后缀不带.** @param file 文件后缀名* @return*/private static String getImageType(File file) {if (file != null && file.exists() && file.isFile()) {String fileName = file.getName();int index = fileName.lastIndexOf(".");if (index != -1 && index < fileName.length() - 1) {return fileName.substring(index + 1);}}return null;}/*** 图片圆角处理,背景透明化** @param srcImageFile 原图片* @param result 处理后图片* @param type 图片格式* @param cornerRadius 720为圆角*/public void makeRoundedCorner(File srcImageFile, File result, String type, int cornerRadius) {try {BufferedImage bi1 = ImageIO.read(srcImageFile);// 根据需要是否使用 BufferedImage.TYPE_INT_ARGBBufferedImage image = new BufferedImage(bi1.getWidth(), bi1.getHeight(),BufferedImage.TYPE_INT_ARGB);Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight());Graphics2D g2 = image.createGraphics();image = g2.getDeviceConfiguration().createCompatibleImage(bi1.getWidth(), bi1.getHeight(), Transparency.TRANSLUCENT);g2 = image.createGraphics();g2.setComposite(AlphaComposite.Clear);g2.fill(new Rectangle(image.getWidth(), image.getHeight()));g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f));g2.setClip(shape);// 使用 setRenderingHint 设置抗锯齿g2 = image.createGraphics();g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2.fillRoundRect(0, 0, bi1.getWidth(), bi1.getHeight(), cornerRadius, cornerRadius);g2.setComposite(AlphaComposite.SrcIn);g2.drawImage(bi1, 0, 0, bi1.getWidth(), bi1.getHeight(), null);g2.dispose();ImageIO.write(image, type, result);} catch (Exception e) {// TODO: handle exception}}/**** @param soursePath 原图地址* @param descPath 新图地址* @param cornerRadius 圆角半径 720正圆形| 40是圆角形* @return* @throws IOException*/public static String makeRoundedCorner(String soursePath, String descPath, int cornerRadius) {BufferedImage image = null;try {image = ImageIO.read(new File(soursePath));/*** 720正圆形* 40是圆角形*/BufferedImage rounded = MergeImgUtil.makeRoundedCorner1(image, cornerRadius);ImageIO.write(rounded, "png", new File(descPath));} catch (IOException e) {e.printStackTrace();}return descPath;}public static void main(String[] args) throws IOException {long startLong = System.currentTimeMillis();//用户评语底图本地保存地址String backgroundPath = "/Users/yuechao/Documents/bruce/works/testpaper/" + "backage.png";System.out.println("backgroundPath :" + backgroundPath);//试卷评语默认头像地址String userHeadImagePath = "/Users/yuechao/Documents/bruce/works/testpaper/" + "head.jpg";System.out.println("userHeadImagePath:" + userHeadImagePath);//圆形头像地址String userHeadImageCircularPath = "/Users/yuechao/Documents/bruce/works/testpaper/" + "head_new.png";makeRoundedCorner(userHeadImagePath,userHeadImageCircularPath,720);//圆形缩放后的图片String userHeadImageCircularSmallPath = "/Users/yuechao/Documents/bruce/works/testpaper/" + "head_new_small.png";reSize(new File(userHeadImageCircularPath),new File(userHeadImageCircularSmallPath),100, 100, true);// MergeImgUtil.imageToCircular(userHeadImagePath, userHeadImageCircularPath, 10, 20);//把用户头像合成到指定底图上MergeImgUtil.mergeImage(backgroundPath,userHeadImageCircularSmallPath,86,958);//皇冠地址//圆形头像地址String headTest = "/Users/yuechao/Documents/bruce/works/testpaper/" + "head-test.png";//把用户头像合成到指定底图上MergeImgUtil.mergeImage(backgroundPath,headTest,50,916);//待存储的地址String tarImgPath = "/Users/yuechao/Documents/bruce/works/testpaper/" + "backage_new.png";//用户昵称String userNickname = "我是张三";//合成图片try {MergeImgUtil.addWaterMark(backgroundPath,tarImgPath,userNickname,198,990,153,31,13,255,32);} catch (IOException e) {e.printStackTrace();}long endLong = System.currentTimeMillis();//time : 1612 //time : 1563System.out.println("time : " + (endLong - startLong)) ;}}

使用示例:

/*** 生成用户得分评语内容* @param busiPaperScoreConfPo 用户得分配置信息* @param busiUserPaperPo 用户答卷信息* @return 上传到OSS之后的地址*/private String getCommentTitleUrl(BusiPaperScoreConfPo busiPaperScoreConfPo, BusiUserPaperPo busiUserPaperPo){Long startTime = System.currentTimeMillis();String randomUserPaperCode = Md5Utils.md5Hex(Math.random() + busiUserPaperPo.getUserPaperCode());//用户评语底图本地保存地址String backgroundPath = randomUserPaperCode + "_baseImg.png";log.debug("getCommentTitleUrl backgroundPath = {}", backgroundPath);//下载用户评语图片到本地DownloadUtil.download(busiPaperScoreConfPo.getCommentTitleUrl(), backgroundPath);//试卷评语默认头像地址String userHeadImagePath = busiUserPaperPo.getUserId() + "_headBaseImg.png";log.debug("getCommentTitleUrl userHeadImagePath + {}", userHeadImagePath);//用户头像网络地址String userHeadImageUrl = apolloConfig.getPaperCommentDefaultHeadImageUrl();UserInfoModel userInfoModel = userInfoGrpcClient.getUserInfoByUserId(busiUserPaperPo.getUserId());if(userInfoModel != null && StringUtils.isNotBlank(userInfoModel.getHeadImgUrl())){log.debug("userInfoModel.getHeadImgUrl() = {}", userInfoModel.getHeadImgUrl());userHeadImageUrl = userInfoModel.getHeadImgUrl();}//下载用户头像到本地DownloadUtil.download(userHeadImageUrl, userHeadImagePath);//圆形头像地址String userHeadImageCircularPath = busiUserPaperPo.getUserId() + "_headCircularBaseImg.png";//头像变圆MergeImgUtil.makeRoundedCorner(userHeadImagePath,userHeadImageCircularPath,720);//圆形缩放后的图片String userHeadImageCircularSmallPath = busiUserPaperPo.getUserId() + "_headCircularSmallBaseImg.png";//圆形头像缩放MergeImgUtil.reSize(new File(userHeadImageCircularPath),new File(userHeadImageCircularSmallPath),apolloConfig.getInvitePosterPapeUserHeadSmallWide(),apolloConfig.getInvitePosterPapeUserHeadSmallHigh(),true);//把用户头像合成到指定底图上MergeImgUtil.mergeImage(backgroundPath,userHeadImageCircularSmallPath,apolloConfig.getInvitePosterPapeUserHeadWide(),apolloConfig.getInvitePosterPapeUserHeadHigh());//试卷评语皇冠图片String paperCommentCrownImageUrl = apolloConfig.getPaperCommentCrownImageUrl();//皇冠地址//皇冠地址String paperCommentCrownImagePath = busiUserPaperPo.getUserId() + "_headCrownBaseImg.png";//下载皇冠图片到本地DownloadUtil.download(paperCommentCrownImageUrl, paperCommentCrownImagePath);//把皇冠合成到指定底图上MergeImgUtil.mergeImage(backgroundPath,paperCommentCrownImagePath,apolloConfig.getInvitePosterPapeCrownWide(),apolloConfig.getInvitePosterPapeCrownHigh());//待存储的地址String tarImgPath = randomUserPaperCode + ".png";try {//用户昵称String userNickname = apolloConfig.getPaperCommentDefaultUserNickname();if(userInfoModel != null && StringUtils.isNotBlank(userInfoModel.getNickname())){userNickname = userInfoModel.getNickname();if(userInfoModel.getNickname().length() > apolloConfig.getUserPaperMaxNickNameLength().longValue()){userNickname = userInfoModel.getNickname().substring(0, 6);userNickname = userNickname + "...";}}//合成图片try {MergeImgUtil.addWaterMark(backgroundPath,tarImgPath,userNickname,apolloConfig.getInvitePosterPapeUserNicknameWide(),apolloConfig.getInvitePosterPapeUserNicknameHigh(),153,31,13,255,32);} catch (IOException e) {log.error("getCommentTitleUrl addWaterMark has exception." , e);e.printStackTrace();//如果合成字体有问题,则直接返回合成头像后的图片并上上传//用户评语最终合成地址String commentTitlePath = "/invite/posterUrl/testPaper/" + busiUserPaperPo.getPaperCode() + "/" + busiUserPaperPo.getUserPaperCode() + "/" + backgroundPath;cosClientWrapper.putObject(commentTitlePath, new File(backgroundPath));return commentTitlePath;}//用户评语最终合成地址String commentTitlePath = "/invite/posterUrl/testPaper/" + busiUserPaperPo.getPaperCode() + "/" + busiUserPaperPo.getUserPaperCode() + "/" + tarImgPath;cosClientWrapper.putObject(commentTitlePath, new File(tarImgPath));return commentTitlePath;} finally {new File(backgroundPath).delete();new File(userHeadImagePath).delete();new File(userHeadImageCircularPath).delete();new File(userHeadImageCircularSmallPath).delete();new File(paperCommentCrownImagePath).delete();new File(tarImgPath).delete();Long endTime = System.currentTimeMillis();log.info("getCommentTitleUrl end endTime = {}, time = {}", endTime, endTime - startTime);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。