米鼠商城

多快好省,买软件就上米鼠网

最新项目

人才服务

靠谱的IT人才垂直招聘平台

java 生成分享图片(二维码,图片拼接,文字编辑)

  • lkj155
  • 2
  • 2020-03-21 13:34
package com.xwn.utils; import javax.imageio.ImageIO; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.WritableRaster; import java.io.File; import java.io.IOException; import java.net.URL; import java.awt.Rectangle; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.InputStream; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import com.xwn.constant.Constant; import com.xwn.constant.PicConstant; import com.xwn.model.UserInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.util.Assert; import net.coobird.thumbnailator.Thumbnails; import java.awt.RenderingHints; import java.awt.geom.Ellipse2D; /** * 服务端画图 * 绘制,拼接,修改图片 * @author xwn */ public class PictureUtils { private static final Logger log = LoggerFactory.getLogger(PictureUtils.class); private Font font = new Font("微软雅黑", Font.BOLD, 70);// 添加字体的属性设置 private Graphics2D g = null; private int fontsize = 0; private int x = 0; private int y = 0; /** * 导入本地图片到缓冲区 */ public BufferedImage loadImageLocal(String imgName) { try { return ImageIO.read(new File(imgName)); } catch (IOException e) { System.out.println(e.getMessage()); } return null; } /** * 导入网络图片到缓冲区 */ public BufferedImage loadImageUrl(String imgName) { try { URL url = new URL(imgName); return ImageIO.read(url); } catch (IOException e) { System.out.println(e.getMessage()); } return null; } /** * 生成新图片到本地 */ public boolean writeImageLocal(String newImage, BufferedImage img) { boolean isok = false; if (newImage != null && img != null) { try { File outputfile = new File(newImage); isok = ImageIO.write(img, "jpg", outputfile); } catch (IOException e) { System.out.println(e.getMessage()); } } return isok; } /** * 将{@link BufferedImage}生成formatName指定格式的图像数据 * @param source * @param formatName 图像格式名,图像格式名错误则抛出异常 * @return */ public static void wirteBytes(BufferedImage source,String formatName,String newImage){ Assert.notNull(source, "source"); ByteArrayOutputStream output = new ByteArrayOutputStream(); Graphics2D g = null; try { for(BufferedImage s=source;!ImageIO.write(s, formatName, output);){ if(null!=g) { throw new IllegalArgumentException(String.format("not found writer for '%s'",formatName)); } s = new BufferedImage(source.getWidth(),source.getHeight(), BufferedImage.TYPE_INT_RGB); g = s.createGraphics(); g.drawImage(source, 0, 0,null); } } catch (IOException e) { throw new RuntimeException(e); } finally { if (null != g) { g.dispose(); } } } /** * 将指定颜色变透明 只能保存 png jpg * @param imageSrc 图片 * @param mask 颜色 * @return */ public static BufferedImage createImageByMaskColorEx(BufferedImage imageSrc, Color mask) { int x, y; x = imageSrc.getWidth(null); y = imageSrc.getHeight(null); BufferedImage imageDes = new BufferedImage(x, y, BufferedImage.TYPE_4BYTE_ABGR); WritableRaster rasterDes = imageDes.getRaster(); int[] des = new int[4]; while (--x >= 0) { for (int j = 0; j < y; ++j) { int rgb = imageSrc.getRGB(x, j); int sr, sg, sb; sr = (rgb & 0xFF0000) >> 16; sg = (rgb & 0xFF00) >> 8; sb = rgb & 0xFF; if (sr == mask.getRed() && sg == mask.getGreen() && sb == mask.getBlue()) { des[3] = 0; } else { des[0] = sr; des[1] = sg; des[2] = sb; des[3] = 255; } rasterDes.setPixel(x, j, des); } } return imageDes; } /** * 设置颜色 * @param img 图片 * @return */ public BufferedImage setColor(BufferedImage img){ //定义一个数组,存放RGB值 int[] rgb = new int[3]; int width = img.getWidth(); int height = img.getHeight(); int minx = img.getMinTileX(); int miny = img.getMinTileY(); //遍历像素点,判断是否更换颜色 for (int i = minx; i < width; i++) { for (int j = miny; j < height; j++) { //换色 int pixel = img.getRGB(i, j); rgb[0] = (pixel & 0xff0000) >>16; rgb[1] = (pixel & 0xff00) >>8; rgb[2] = (pixel & 0xff) ; if (rgb[0]<230&&rgb[0]>100&& rgb[1]<230&&rgb[1]>100 && rgb[2]<230&&rgb[2]>100) { img.setRGB(i, j, 0xffffff); } } } return img; } /** * 设定文字的字体等 * @param fontStyle 文字字体 * @param fontSize 大小 */ public void setFont(String fontStyle, int fontSize) { this.fontsize = fontSize; this.font = new Font(fontStyle, Font.PLAIN, fontSize); } /** * 修改图片,返回修改后的图片缓冲区(只输出一行文本) */ public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y) { try { int w = img.getWidth(); int h = img.getHeight(); g = img.createGraphics(); g.setBackground(Color.WHITE); g.setColor(Color.BLACK);//设置字体颜色 if (this.font != null) { g.setFont(this.font); } // 验证输出位置的纵坐标和横坐标 if (x >= h || y >= w) { this.x = h - this.fontsize + 2; this.y = w; } else { this.x = x; this.y = y; } g.setFont( new Font("微软雅黑", Font.BOLD, 22)); if (content != null) { g.drawString(content.toString(), this.x, this.y); } g.setBackground(Color.WHITE); g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return img; } /** * 修改图片,返回修改后的图片缓冲区(只输出一行文本) * @param img 图片 * @return */ public BufferedImage modifyImageYe(BufferedImage img) { try { int w = img.getWidth(); int h = img.getHeight(); g = img.createGraphics(); g.setBackground(Color.WHITE); g.setColor(Color.blue);//设置字体颜色 if (this.font != null) g.setFont(this.font); g.drawString("reyo.cn", w - 85, h - 5); g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return img; } /** * 合成图片 * @param b 图片b * @param d 图片d * @param x x坐标 * @param y y坐标 * @param height 高度 * @param weight 宽度 * @return */ public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d,int x,int y,int height ,int weight) { try { g = d.createGraphics(); g.drawImage(b, x, y, weight, height, null); g.dispose(); } catch (Exception e) { System.out.println(e.getMessage()); } return d; } /** * 对图片进行剪裁 返回字节数组 * @param is 图片输入流 * @param width 裁剪图片的宽 * @param height 裁剪图片的高 * @param imageFormat 输出图片的格式 "jpeg jpg等" * @return */ public static byte[] clipImage(InputStream is,int width, int height, String imageFormat){ ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { // 构造Image对象 BufferedImage src = javax.imageio.ImageIO.read(is); // 缩小边长 BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 绘制 缩小 后的图片 tag.getGraphics().drawImage(src, 0, 0, width, height, null); ImageIO.write(tag, imageFormat, bos); } catch (IOException e) { e.printStackTrace(); } return bos.toByteArray(); } /** * 对图片裁剪,并把裁剪新图片保存 * @param srcPath 读取源图片路径 * @param toPath 写入图片路径 * @param x 剪切起始点x坐标 * @param y 剪切起始点y坐标 * @param width 剪切宽度 * @param height 剪切高度 * @param readImageFormat 读取图片格式 * @param writeImageFormat 写入图片格式 */ public static void cropImage(String srcPath, String toPath, int x,int y,int width,int height, String readImageFormat,String writeImageFormat){ FileInputStream fis = null ; ImageInputStream iis =null ; try{ //读取图片文件 fis = new FileInputStream(srcPath); Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(readImageFormat); ImageReader reader = readers.next(); //获取图片流 iis = ImageIO.createImageInputStream(fis); reader.setInput(iis, true); ImageReadParam param = reader.getDefaultReadParam(); //定义一个矩形 Rectangle rect = new Rectangle(x, y, width, height); //提供一个 BufferedImage,将其用作解码像素数据的目标。 param.setSourceRegion(rect); BufferedImage bi = reader.read(0, param); //保存新图片 ImageIO.write(bi, writeImageFormat, new File(toPath)); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(fis!=null){ fis.close(); } if(iis!=null){ iis.close(); } }catch(Exception e){ e.printStackTrace(); } } } /** * 传入的图像必须是正方形的 才会 圆形 如果是长方形的比例则会变成椭圆的 * @param bi1 图片 * @return * @throws IOException */ public static BufferedImage convertCircular(BufferedImage bi1) throws IOException { // 透明底的图片 BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight()); Graphics2D g2 = bi2.createGraphics(); g2.setClip(shape); // 使用 setRenderingHint 设置抗锯齿 g2.drawImage(bi1, 0, 0, null); // 设置颜色 g2.setBackground(Color.green); g2.dispose(); return bi2; } /** * 缩小Image,此方法返回源图像按给定宽度、高度限制下缩放后的图像 * @param inputImage * @param newWidth:压缩后宽度 * @param newHeight:压缩后高度 * @param beijing:背景图片 * @throws java.io.IOException */ public static BufferedImage scaleByPercentage(BufferedImage inputImage, int newWidth, int newHeight,BufferedImage beijing) throws Exception { // 获取原始图像透明度类型 int type = inputImage.getColorModel().getTransparency(); int width = inputImage.getWidth(); int height = inputImage.getHeight(); // 开启抗锯齿 RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 使用高质量压缩 renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); BufferedImage img = new BufferedImage(newWidth, newHeight, type); Graphics2D graphics2d = img.createGraphics(); graphics2d.setRenderingHints(renderingHints); graphics2d.drawImage(inputImage, 0, 0, newWidth, newHeight, 0, 0, width, height, null); graphics2d.dispose(); return img; } /** * 头像缩放 四舍五入 double转int * @param beijing_ * @return */ public static Integer doubleToInt(BufferedImage beijing_,double d){ return (new Double((d*beijing_.getHeight()))).intValue(); } /** * 让字符串隔开展现 * @param code * @return */ public static String getCode(String code){ StringBuilder sb = new StringBuilder(); for (int i = 0; i < code.length(); i++) { if(i != (code.length()-1)){ sb.append(code.charAt(i)).append(" "); }else{ sb.append(code.charAt(i)); } } return sb.toString(); } /** * 网络图片输出到BufferedImage * @throws IOException */ private BufferedImage getBufferedImageForURL(String filePath) throws IOException { //asBufferedImage() 返回BufferedImage BufferedImage thumbnail = Thumbnails.of(new URL(filePath)) .scale(1) .asBufferedImage(); return thumbnail; } /** * 本地图片输出到BufferedImage * @throws IOException */ private BufferedImage getBufferedImageForLocal(String filePath) throws IOException { /** * asBufferedImage() 返回BufferedImage */ BufferedImage thumbnail = Thumbnails.of(filePath) .scale(1) .asBufferedImage(); return thumbnail; } /** * 合成图片 * @param user 用户 * @throws IOException */ public static void initImage(UserInfo user) throws IOException { Map<String,String> map = new HashMap<String,String>(); PictureUtils tt = new PictureUtils(); String baseUrl = Constant.BASE_URL; String beijing = PicConstant.yaoqingbeijing128; String dibian = PicConstant.yaoqingdibian128; //底边合成背景 String newPicUrl = new StringBuffer(baseUrl).append("ok/").append(user.getUserId()).append(".jpg").toString(); if(!new File(newPicUrl).exists()){ //获取绑定二维码图片 Map<String,String> qrCodeMap = QrCodeUtil.getUserQrImgURL(user); if(qrCodeMap != null){ String qrCodeImgURL = qrCodeMap.get("qrPath"); String qrCode = qrCodeMap.get("qrCode"); boolean isOk = true; try { BufferedImage head_ = tt.getBufferedImageForURL(user.getHeadImgUrl()); BufferedImage qrCodeImg = tt.getBufferedImageForLocal(qrCodeImgURL); BufferedImage beijing_ = tt.getBufferedImageForURL(beijing); BufferedImage dibian_ = tt.getBufferedImageForURL(dibian); head_ = convertCircular(head_); head_ = scaleByPercentage(head_, doubleToInt(dibian_,PicConstant.DOUBLE_TO_INT_HEAD), doubleToInt(dibian_,PicConstant.DOUBLE_TO_INT_HEAD),beijing_); isOk = tt.writeImageLocal(new StringBuilder(baseUrl).append("head.jpg").toString(),head_); //合成头像 int x = 30; int y = 75; int weight1 = head_.getWidth(); int height1 = head_.getHeight(); tt.modifyImagetogeter(head_, dibian_,x,y,height1,weight1); isOk = tt.writeImageLocal(new StringBuilder(baseUrl).append("dibian.jpg").toString(), tt.modifyImagetogeter(head_, dibian_,x,y,height1,weight1)); //添加文字 x = 100; y = 135; tt.modifyImage(dibian_,getCode(user.getInviteCode()),x,y); isOk = tt.writeImageLocal(new StringBuilder(baseUrl).append("xiabufen1.jpg").toString(),tt.modifyImage(dibian_,getCode(user.getInviteCode()),x,y)); //合成二维码 x = 325; y = 12; int weight3 = doubleToInt(qrCodeImg,PicConstant.DOUBLE_TO_INT_QR); int height3 = doubleToInt(qrCodeImg,PicConstant.DOUBLE_TO_INT_QR); tt.modifyImagetogeter(qrCodeImg, dibian_,x,y,doubleToInt(qrCodeImg,PicConstant.DOUBLE_TO_INT_QR),doubleToInt(qrCodeImg,PicConstant.DOUBLE_TO_INT_QR)); isOk = tt.writeImageLocal(new StringBuilder(baseUrl).append("xiabufen2.jpg").toString(), tt.modifyImagetogeter(qrCodeImg, dibian_,x,y,height3,weight3)); x = 0; y = beijing_.getHeight()-dibian_.getHeight(); int weight = dibian_.getWidth(); int height = dibian_.getHeight(); isOk = tt.writeImageLocal(newPicUrl, tt.modifyImagetogeter(dibian_, beijing_,x,y,height,weight)); } catch (Exception e) { log.error("合成"+ e.getMessage()); } if(!isOk){ log.error("生成图片失败!"); } map.put("qrCode", qrCode); map.put("newPicUrl", newPicUrl); } }else{ map.put("qrCode", new StringBuffer(Constant.DEFAULT_IMG_BASEURL).append(user.getUserId()).toString()); map.put("newPicUrl", newPicUrl); } log.info(map.toString()); } public static void main(String[] args) throws IOException { UserInfo user = new UserInfo(); user.setUserId(1); user.setHeadImgUrl(PicConstant.Head_Test); user.setInviteCode("123456"); initImage(user); } }

这里给大家推荐一个在线软件复杂项交易平台:米鼠网 https://www.misuland.com

米鼠网自成立以来一直专注于从事软件项目人才招聘软件商城等,始终秉承“专业的服务,易用的产品”的经营理念,以“提供高品质的服务、满足客户的需求、携手共创双赢”为企业目标,为中国境内企业提供国际化、专业化、个性化、的软件项目解决方案,我司拥有一流的项目经理团队,具备过硬的软件项目设计和实施能力,为全国不同行业客户提供优质的产品和服务,得到了客户的广泛赞誉。



如有侵权请联系邮箱(service@misuland.com)

猜你喜欢

评论留言