package com.yeshi.fanli.util; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.FontFormatException; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigDecimal; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import javax.imageio.ImageIO; import org.yeshi.utils.HttpUtil; import com.yeshi.fanli.entity.bus.activity.RecommendActivityTaoBaoGoods; import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief; import com.yeshi.fanli.log.LogHelper; import com.yeshi.fanli.util.taobao.TaoBaoUtil; public class ImageUtil { // 画商品分享图 public static InputStream drawGoodsShareImg(InputStream qrcodeStream, InputStream portrait, TaoBaoGoodsBrief goods) { String fontPath = "/usr/share/fonts/PingFang_Medium.ttf"; String os = System.getProperty("os.name"); if (os.toLowerCase().startsWith("win")) { fontPath = "D:/PingFang_Medium.ttf"; } String fontBoldPath = "/usr/share/fonts/PingFang_Heavy_0.ttf"; if (os.toLowerCase().startsWith("win")) { fontBoldPath = "D:/PingFang_Heavy_0.ttf"; } final BufferedImage targetImg = new BufferedImage(720, 1280, BufferedImage.TYPE_INT_RGB); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  final Graphics2D g2d = (Graphics2D) targetImg.getGraphics(); g2d.setRenderingHints(mapH); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, 720, 1280); Font font = null; try { font = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(30.0f); } catch (FontFormatException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } g2d.setFont(font); try { g2d.setColor(new Color(153, 153, 153)); // 画来源图标 InputStream userTypeIcon = null; if (goods.getUserType() == 0)// 淘宝 { userTypeIcon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_tb.png"); } else { userTypeIcon = ImageUtil.class.getClassLoader().getResourceAsStream("image/icon_tm.png"); } g2d.drawImage(ImageIO.read(userTypeIcon), 50, 88, null); // 商品标题 String title = goods.getTitle(); int row = 0; int length = 0; // 画第一排 length = getTextLengthByWidth(g2d, font, title, 500, 10); g2d.drawString(title.substring(0, length), 50 + 65, 112 + row * 40); title = title.substring(length); row++; // 判断是否画完,最多画2排 while (title.length() > 0 && row < 2) { length = getTextLengthByWidth(g2d, font, title, 335, 10); g2d.drawString(title.substring(0, length), 50, 112 + row * 40); title = title.substring(length); row++; } // 画商品主图 InputStream goodsPicture = TaoBaoHttpUtil.getAsInputStream(goods.getPictUrl()); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 620, 620); g2d.drawImage(picImage, 50, 190, null); Font boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(50.0f); // 画价格 // 有券 if (!StringUtil.isNullOrEmpty(goods.getCouponInfo())) { BigDecimal finalPrice = goods.getZkPrice(); if (goods.getCouponStartFee().compareTo(goods.getZkPrice()) <= 0 && goods.getZkPrice().compareTo(goods.getCouponAmount()) >= 0) { finalPrice = goods.getZkPrice().subtract(goods.getCouponAmount()); } g2d.setColor(new Color(229, 0, 93)); g2d.drawString("券后价 ¥", 57, 875); g2d.setColor(new Color(229, 0, 93)); g2d.setFont(boldFont); g2d.drawString(finalPrice.toString(), 85 + 110, 875); // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_right.png")); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, 670 - quanRight.getWidth(), 852, null); // 画券的内容 g2d.setColor(new Color(229, 0, 93)); String quanString = " " + MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()) + "元券 "; boldFont = boldFont.deriveFont(44.0f); g2d.setFont(boldFont); FontMetrics fm = g2d.getFontMetrics(boldFont); int textLength = fm.stringWidth(quanString); g2d.fillRect(670 - quanRight.getWidth() - textLength, 852, textLength, 80); g2d.setColor(Color.WHITE); g2d.setFont(boldFont); g2d.drawString(quanString, 670 - quanRight.getWidth() - textLength, 927 - 19); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_left.png")); g2d.drawImage(quanLeft, 670 - quanRight.getWidth() - textLength - quanLeft.getWidth(), 852, null); String zkPriceName = ""; if (goods.getUserType() == 0) zkPriceName = "淘宝价 ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()); else zkPriceName = "天猫价 ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()); g2d.setColor(new Color(153, 153, 153)); font = font.deriveFont(30.0f); g2d.setFont(font); g2d.drawString(zkPriceName, 56, 930); } else// 无券 { g2d.setColor(new Color(229, 0, 93)); g2d.drawString("¥", 60, 870); g2d.setColor(new Color(229, 0, 93)); BigDecimal finalPrice = goods.getZkPrice(); g2d.setFont(boldFont); g2d.drawString(finalPrice.toString(), 85, 870); } g2d.setColor(new Color(247, 247, 247)); g2d.fillRect(56, 1015, 608, 204); // 画二维码 BufferedImage qrcodeImage = ImageIO.read(qrcodeStream); qrcodeImage = zoomInImage(qrcodeImage, 170, 170); g2d.drawImage(qrcodeImage, 56 + 17, 1015 + 17, null); // 画头像 if (portrait != null) { BufferedImage portraitImg = ImageIO.read(portrait); portraitImg = zoomInImage(portraitImg, 40, 40); g2d.drawImage(portraitImg, 56 + 17 + (qrcodeImage.getWidth() - portraitImg.getWidth()) / 2, 1015 + 17 + (qrcodeImage.getHeight() - portraitImg.getHeight()) / 2, null); } font = font.deriveFont(30.0f); g2d.setFont(font); g2d.setColor(new Color(229, 0, 93)); // g2d.drawString("返利券提醒您", 250 + 17, 1080 + 17); g2d.setColor(new Color(102, 102, 102)); g2d.drawString("长按识别二维码领取优惠券", 250 + 17, 1130 + 17); g2d.dispose(); // OutputStream out = new ByteArrayOutputStream(); new // FileOutputStream(new File(targetPath)); // ImageIO.write(targetImg, "JPEG", out); // out.flush(); // out.close(); ByteArrayOutputStream aos = new ByteArrayOutputStream(); ImageIO.write(targetImg, "JPEG", aos); InputStream is = new ByteArrayInputStream(aos.toByteArray()); return is; } catch (Exception e) { try { LogHelper.errorDetailInfo(e); } catch (Exception e1) { e1.printStackTrace(); } } return null; } /** * 绘制大的商品动态分享图 * * @param qrcodeStream * @param portrait * @param goods * @return */ public static InputStream drawActivityGoodsShareBigImg(InputStream qrcodeStream, InputStream portrait, List goodsList) { String fontPath = "/usr/share/fonts/PingFang_Medium.ttf"; String os = System.getProperty("os.name"); if (os.toLowerCase().startsWith("win")) { fontPath = "D:/PingFang_Medium.ttf"; } String fontBoldPath = "/usr/share/fonts/PingFang_Heavy_0.ttf"; if (os.toLowerCase().startsWith("win")) { fontBoldPath = "D:/PingFang_Heavy_0.ttf"; } final BufferedImage targetImg = new BufferedImage(1420, 1334, BufferedImage.TYPE_INT_RGB); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  final Graphics2D g2d = (Graphics2D) targetImg.getGraphics(); g2d.setRenderingHints(mapH); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, 1420, 1334); Font font = null; try { font = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(30.0f); } catch (FontFormatException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } Font boldFont = null; try { boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(50.0f); } catch (FontFormatException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } g2d.setFont(font); try { g2d.setColor(new Color(153, 153, 153)); // 画第一张 for (int i = 0; i < goodsList.size(); i++) { RecommendActivityTaoBaoGoods goods = goodsList.get(i); // 第一张图需要有价格信息 if (i == 0) { int topX = 50; int topY = 50; // 画大图 起始点坐标为(50,50) InputStream goodsPicture = TaoBaoHttpUtil .getAsInputStream(goods.getPictUrl().replace("_.webp", "").replace("_220x220", "")); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 650, 650); g2d.drawImage(picImage, topX, topX, null); g2d.setColor(new Color(224, 224, 224)); // 画边框 g2d.setStroke(new BasicStroke(1.0f)); g2d.drawRect(topX - 1, topY - 1, 651, 651); // 画透明背景 g2d.setColor(new Color(255, 255, 255, 210)); g2d.fillRect(50, 600, 650, 100); // 画金额 g2d.setColor(new Color(240, 0, 102)); boldFont = boldFont.deriveFont(22.0f); g2d.setFont(boldFont); g2d.drawString("¥", 70, 650); boldFont = boldFont.deriveFont(42.0f); g2d.setFont(boldFont); g2d.drawString(goods.getQuanPrice(), 90, 650); // 画原价 g2d.setColor(new Color(102, 102, 102)); font = font.deriveFont(24.0f); g2d.setFont(font); String zkPrice = new BigDecimal(goods.getQuanPrice().replace("¥", "")).add(goods.getCouponAmount()) .toString(); g2d.drawString("¥ " + zkPrice, 70, 650 + 33); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth(zkPrice); // 画删除线 g2d.setStroke(new BasicStroke(2.0f)); g2d.drawLine(70 + 20, 674, 90 + 10 + textLength, 674); // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_right.png")); quanRight = zoomInImage(quanRight, 12, 60); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, topX + 630 - quanRight.getWidth(), topY + 630 - quanRight.getHeight(), null); // 画券的内容 g2d.setColor(new Color(229, 0, 93)); String quanString = " " + MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()) + "元券 "; font = font.deriveFont(36.0f); g2d.setFont(font); fm = g2d.getFontMetrics(font); textLength = fm.stringWidth(quanString); g2d.fillRect(topX + 630 - quanRight.getWidth() - textLength, topY + 630 - quanRight.getHeight(), textLength, quanRight.getHeight()); g2d.setColor(Color.WHITE); g2d.drawString(quanString, topX + 630 - quanRight.getWidth() - textLength, topY + 630 + 42 - quanRight.getHeight()); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_left.png")); quanLeft = zoomInImage(quanLeft, 12, 60); g2d.drawImage(quanLeft, topX + 630 - quanRight.getWidth() - textLength - quanLeft.getWidth(), topY + 630 - quanRight.getHeight(), null); } else { // 计算左上角坐标 int topX = 0; int topY = 0; if (i == 1) topX = 50 + (315 + 20) * 0; else if (i == 2 || i % 2 != 0)// 2,3,5,7 topX = 50 + (315 + 20) * (i % 2 + 1); else if (i % 2 == 0)// 4,6,8 topX = 50 + (315 + 20) * 3; if (i == 1 || i == 2) topY = 50 + 650 + 20; else if (i == 3 || i == 4) topY = 50; else if (i == 5 || i == 6) topY = 50 + (315 + 20) * 1; else if (i == 7 || i == 8) topY = 50 + (315 + 20) * 2; // 画大图 InputStream goodsPicture = TaoBaoHttpUtil .getAsInputStream(goods.getPictUrl().replace("_.webp", "")); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 315, 315); g2d.drawImage(picImage, topX, topY, null); g2d.setColor(new Color(224, 224, 224)); // 画边框 g2d.setStroke(new BasicStroke(1.0f)); g2d.drawRect(topX - 1, topY - 1, 316, 316); // 画券 // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_right.png")); quanRight = zoomInImage(quanRight, 8, 40); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, topX + 315 - quanRight.getWidth(), topY + 315 - quanRight.getHeight(), null); // 画券的内容 g2d.setColor(new Color(229, 0, 93)); String quanString = " " + MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()) + "元券 "; font = font.deriveFont(24.0f); g2d.setFont(font); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth(quanString); g2d.fillRect(topX + 315 - quanRight.getWidth() - textLength, topY + 315 - quanRight.getHeight(), textLength, quanRight.getHeight()); g2d.setColor(Color.WHITE); g2d.setFont(font); g2d.drawString(quanString, topX + 315 - quanRight.getWidth() - textLength, topY + 315 + 28 - quanRight.getHeight()); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_left.png")); quanLeft = zoomInImage(quanLeft, 8, 40); g2d.drawImage(quanLeft, topX + 315 - quanRight.getWidth() - textLength - quanLeft.getWidth(), topY + 315 - quanRight.getHeight(), null); } } g2d.setColor(new Color(247, 247, 247)); g2d.fillRect(50, 1070, 1320, 214); // 画二维码 BufferedImage qrcodeImage = ImageIO.read(qrcodeStream); qrcodeImage = zoomInImage(qrcodeImage, 170, 170); g2d.drawImage(qrcodeImage, 70, 1092, null); // 画头像 if (portrait != null) { BufferedImage portraitImg = ImageIO.read(portrait); portraitImg = zoomInImage(portraitImg, 40, 40); g2d.drawImage(portraitImg, 70 + (qrcodeImage.getWidth() - portraitImg.getWidth()) / 2, 1092 + (qrcodeImage.getHeight() - portraitImg.getHeight()) / 2, null); } font = font.deriveFont(50.0f); g2d.setFont(font); g2d.setColor(new Color(229, 0, 93)); // g2d.drawString("返利券提醒您", 312, 1118 + 40); g2d.setColor(new Color(102, 102, 102)); g2d.drawString("长按识别二维码领取优惠券", 312, 1118 + 77); g2d.dispose(); // OutputStream out = new ByteArrayOutputStream(); new // FileOutputStream(new File(targetPath)); // ImageIO.write(targetImg, "JPEG", out); // out.flush(); // out.close(); ByteArrayOutputStream aos = new ByteArrayOutputStream(); ImageIO.write(targetImg, "JPEG", aos); InputStream is = new ByteArrayInputStream(aos.toByteArray()); return is; } catch (Exception e) { try { LogHelper.errorDetailInfo(e); } catch (Exception e1) { e1.printStackTrace(); } } return null; } /** * 绘制大的商品动态分享图 * * @param qrcodeStream * @param portrait * @param goods * @return */ public static InputStream drawGoodsShareBigImg(InputStream qrcodeStream, InputStream portrait, List goodsList) { String fontPath = "/usr/share/fonts/PingFang_Medium.ttf"; String os = System.getProperty("os.name"); if (os.toLowerCase().startsWith("win")) { fontPath = "D:/PingFang_Medium.ttf"; } String fontBoldPath = "/usr/share/fonts/PingFang_Heavy_0.ttf"; if (os.toLowerCase().startsWith("win")) { fontBoldPath = "D:/PingFang_Heavy_0.ttf"; } final BufferedImage targetImg = new BufferedImage(1420, 1334, BufferedImage.TYPE_INT_RGB); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  final Graphics2D g2d = (Graphics2D) targetImg.getGraphics(); g2d.setRenderingHints(mapH); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, 1420, 1334); Font font = null; try { font = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(30.0f); } catch (FontFormatException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } Font boldFont = null; try { boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(50.0f); } catch (FontFormatException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } g2d.setFont(font); try { // g2d.setColor(new Color(153, 153, 153)); // 画第一张 for (int i = 0; i < goodsList.size(); i++) { TaoBaoGoodsBrief goods = goodsList.get(i); BigDecimal couplePrice = TaoBaoUtil.getAfterUseCouplePrice(goods); // 第一张图需要有价格信息 if (i == 0) { int topX = 50; int topY = 50; // 画大图 起始点坐标为(50,50) InputStream goodsPicture = TaoBaoHttpUtil .getAsInputStream(goods.getPictUrl().replace("_.webp", "").replace("_220x220", "")); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 650, 650); g2d.drawImage(picImage, topX, topX, null); g2d.setColor(new Color(224, 224, 224)); // 画边框 g2d.setStroke(new BasicStroke(1.0f)); g2d.drawRect(topX - 1, topY - 1, 651, 651); // 画透明背景 g2d.setColor(new Color(255, 255, 255, 210)); g2d.fillRect(50, 600, 650, 100); // 画金额 g2d.setColor(new Color(240, 0, 102)); boldFont = boldFont.deriveFont(22.0f); g2d.setFont(boldFont); g2d.drawString("¥", 70, 650); boldFont = boldFont.deriveFont(42.0f); g2d.setFont(boldFont); g2d.drawString(couplePrice+"", 90, 650); // 画原价 g2d.setColor(new Color(102, 102, 102)); font = font.deriveFont(24.0f); g2d.setFont(font); String zkPrice = new BigDecimal((couplePrice+"").replace("¥", "")).add(goods.getCouponAmount()) .toString(); g2d.drawString("¥ " + zkPrice, 70, 650 + 33); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth(zkPrice); // 画删除线 g2d.setStroke(new BasicStroke(2.0f)); g2d.drawLine(70 + 20, 674, 90 + 10 + textLength, 674); String quanString = ""; BigDecimal withNoZera = MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()); if (!withNoZera.toString().endsWith("0")) { // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_right.png")); quanRight = zoomInImage(quanRight, 12, 60); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, topX + 630 - quanRight.getWidth(), topY + 630 - quanRight.getHeight(), null); // 画券的内容 g2d.setColor(new Color(229, 0, 93)); quanString = " " + withNoZera + "元券 "; font = font.deriveFont(36.0f); g2d.setFont(font); fm = g2d.getFontMetrics(font); textLength = fm.stringWidth(quanString); g2d.fillRect(topX + 630 - quanRight.getWidth() - textLength, topY + 630 - quanRight.getHeight(), textLength, quanRight.getHeight()); g2d.setColor(Color.WHITE); g2d.drawString(quanString, topX + 630 - quanRight.getWidth() - textLength, topY + 630 + 42 - quanRight.getHeight()); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_left.png")); quanLeft = zoomInImage(quanLeft, 12, 60); g2d.drawImage(quanLeft, topX + 630 - quanRight.getWidth() - textLength - quanLeft.getWidth(), topY + 630 - quanRight.getHeight(), null); } } else { // 计算左上角坐标 int topX = 0; int topY = 0; if (i == 1) topX = 50 + (315 + 20) * 0; else if (i == 2 || i % 2 != 0)// 2,3,5,7 topX = 50 + (315 + 20) * (i % 2 + 1); else if (i % 2 == 0)// 4,6,8 topX = 50 + (315 + 20) * 3; if (i == 1 || i == 2) topY = 50 + 650 + 20; else if (i == 3 || i == 4) topY = 50; else if (i == 5 || i == 6) topY = 50 + (315 + 20) * 1; else if (i == 7 || i == 8) topY = 50 + (315 + 20) * 2; // 画大图 InputStream goodsPicture = TaoBaoHttpUtil .getAsInputStream(goods.getPictUrl().replace("_.webp", "")); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 315, 315); g2d.drawImage(picImage, topX, topY, null); g2d.setColor(new Color(224, 224, 224)); // 画边框 g2d.setStroke(new BasicStroke(1.0f)); g2d.drawRect(topX - 1, topY - 1, 316, 316); // 画券 String quanString = ""; BigDecimal withNoZera = MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()); if (!withNoZera.toString().endsWith("0")) { // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_right.png")); quanRight = zoomInImage(quanRight, 8, 40); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, topX + 315 - quanRight.getWidth(), topY + 315 - quanRight.getHeight(), null); // 画券的内容 g2d.setColor(new Color(229, 0, 93)); quanString = " " + withNoZera + "元券 "; font = font.deriveFont(24.0f); g2d.setFont(font); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth(quanString); g2d.fillRect(topX + 315 - quanRight.getWidth() - textLength, topY + 315 - quanRight.getHeight(), textLength, quanRight.getHeight()); g2d.setColor(Color.WHITE); g2d.setFont(font); g2d.drawString(quanString, topX + 315 - quanRight.getWidth() - textLength, topY + 315 + 28 - quanRight.getHeight()); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/fanli_quan_left.png")); quanLeft = zoomInImage(quanLeft, 8, 40); g2d.drawImage(quanLeft, topX + 315 - quanRight.getWidth() - textLength - quanLeft.getWidth(), topY + 315 - quanRight.getHeight(), null); } } } g2d.setColor(new Color(247, 247, 247)); g2d.fillRect(50, 1070, 1320, 214); // 画二维码 BufferedImage qrcodeImage = ImageIO.read(qrcodeStream); qrcodeImage = zoomInImage(qrcodeImage, 170, 170); g2d.drawImage(qrcodeImage, 70, 1092, null); // 画头像 if (portrait != null) { BufferedImage portraitImg = ImageIO.read(portrait); // 放缩大小 portraitImg = zoomInImage(portraitImg, 40,40); // 圆角 portraitImg = roundImage(portraitImg, 10); g2d.drawImage(portraitImg, 70 + (qrcodeImage.getWidth() - portraitImg.getWidth()) / 2, 1092 + (qrcodeImage.getHeight() - portraitImg.getHeight()) / 2, null); } font = font.deriveFont(50.0f); g2d.setFont(font); g2d.setColor(new Color(229, 0, 93)); // g2d.drawString("返利券提醒您", 312, 1118 + 40); g2d.setColor(new Color(102, 102, 102)); g2d.drawString("长按识别二维码免费领券", 312, 1150); g2d.setColor(new Color(102, 102, 102)); g2d.drawString("共", 1000, 1150); g2d.setColor(new Color(229, 0, 93)); g2d.drawString(goodsList.size()+"", 1055, 1150); g2d.setColor(new Color(102, 102, 102)); g2d.drawString("个商品", 1090, 1150); // 提示语 BufferedImage tips = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/share/tips1.png")); tips = zoomInImage(tips,850, 65); g2d.drawImage(tips, 312,1190, null); g2d.dispose(); ByteArrayOutputStream aos = new ByteArrayOutputStream(); ImageIO.write(targetImg, "JPEG", aos); InputStream is = new ByteArrayInputStream(aos.toByteArray()); return is; } catch (Exception e) { try { LogHelper.errorDetailInfo(e); } catch (Exception e1) { e1.printStackTrace(); } } return null; } // 画商品分享图 public static InputStream drawGoodsShareImgHCJ(InputStream qrcodeStream, InputStream portrait, TaoBaoGoodsBrief goods) throws Exception { String fontPath = "/usr/share/fonts/PingFang_Medium.ttf"; String os = System.getProperty("os.name"); if (os.toLowerCase().startsWith("win")) { fontPath = "D:/PingFang_Medium.ttf"; } String fontBoldPath = "/usr/share/fonts/PingFang_Heavy_0.ttf"; if (os.toLowerCase().startsWith("win")) { fontBoldPath = "D:/PingFang_Heavy_0.ttf"; } Font font = null; Font boldFont = null; font = Font.createFont(Font.PLAIN, new File(fontPath)).deriveFont(28.0f); boldFont = Font.createFont(Font.PLAIN, new File(fontBoldPath)).deriveFont(28.0f); final BufferedImage targetImg = new BufferedImage(720, 1280, BufferedImage.TYPE_INT_RGB); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  final Graphics2D g2d = (Graphics2D) targetImg.getGraphics(); g2d.setRenderingHints(mapH); g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, 720, 1280); g2d.setFont(font.deriveFont(28.0f)); // 画广告语 InputStream adTitle = ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_share_title_icon.png"); if (adTitle != null) { BufferedImage adTitleImage = ImageIO.read(adTitle); g2d.drawImage(adTitleImage, 192, 101, null); } // 画商品主图 InputStream goodsPicture = TaoBaoHttpUtil.getAsInputStream(goods.getPictUrl().replace("https://", "http://")); BufferedImage picImage = ImageIO.read(goodsPicture); picImage = zoomInImage(picImage, 620, 620); g2d.drawImage(picImage, 50, 207, null); // 画价格 BigDecimal money = TaoBaoUtil.getAfterUseCouplePrice(goods); money = MoneyBigDecimalUtil.getWithNoZera(money); g2d.setColor(new Color(240, 66, 66)); g2d.setFont(boldFont.deriveFont(30.0f)); g2d.drawString("¥", 62, 900); g2d.setFont(boldFont.deriveFont(56.0f)); g2d.drawString(money.toString(), 90, 900); g2d.setFont(font.deriveFont(56.0f)); g2d.setColor(new Color(153, 153, 153)); if (!StringUtil.isNullOrEmpty(goods.getCouponInfo())) { // 画天猫价或者淘宝价 String zkPriceName = ""; if (goods.getUserType() == 0) zkPriceName = "淘宝价 ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()); else zkPriceName = "天猫价 ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getZkPrice()); font = font.deriveFont(30.0f); g2d.setFont(font); g2d.drawString(zkPriceName, 56, 955); // 画券右侧 BufferedImage quanRight = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_quan_right.png")); g2d.setColor(new Color(241, 66, 66)); g2d.drawImage(quanRight, 670 - quanRight.getWidth(), 867, null); // 画券的内容 g2d.setColor(new Color(241, 66, 66)); String quanString = " ¥ " + MoneyBigDecimalUtil.getWithNoZera(goods.getCouponAmount()) + " 券 "; font = font.deriveFont(44.0f); g2d.setFont(font); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth(quanString); g2d.fillRect(670 - quanRight.getWidth() - textLength, 872, textLength, 80); g2d.setColor(Color.WHITE); g2d.setFont(font); g2d.drawString(quanString, 670 - quanRight.getWidth() - textLength, 927); // 画券左侧 BufferedImage quanLeft = ImageIO .read(ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_quan_left.png")); g2d.drawImage(quanLeft, 670 - quanRight.getWidth() - textLength - quanLeft.getWidth(), 867, null); } InputStream userTypeIcon; if (goods.getUserType() == 0)// 淘宝 { userTypeIcon = ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_icon_tb.png"); } else { userTypeIcon = ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_icon_tm.png"); } g2d.drawImage(ImageIO.read(userTypeIcon), 63, 1022, null); String title = goods.getTitle(); // 商品标题 font = font.deriveFont(30.0f); g2d.setFont(font); int length = getTextLengthByWidth(g2d, font, title, 290, 8); g2d.setColor(new Color(153, 153, 153)); int row = 0; // 画第一排 g2d.drawString(title.substring(0, length), 20 + 50 + 46, 1044 + row * 40); if (length < title.length()) title = title.substring(length); else title = ""; // 判断是否画完 row++; while (title.length() > 0) { length = getTextLengthByWidth(g2d, font, title, 330, 10); g2d.drawString(title.substring(0, length), 63, 1044 + row * 40); title = title.substring(length); row++; } // 画边框 InputStream erCodeSide = ImageUtil.class.getClassLoader().getResourceAsStream("image/hcj_ercode_side.png"); BufferedImage erCodeSideImage = ImageIO.read(erCodeSide); erCodeSideImage = zoomInImage(erCodeSideImage, 200, 200); g2d.drawImage(erCodeSideImage, 466, 986, null); // 画二维码 BufferedImage qrcodeImage = ImageIO.read(qrcodeStream); qrcodeImage = zoomInImage(qrcodeImage, 170, 170); g2d.drawImage(qrcodeImage, 481, 1000, null); // 画头像 if (portrait != null) { BufferedImage portraitImg = ImageIO.read(portrait); portraitImg = zoomInImage(portraitImg, 30, 30); g2d.drawImage(portraitImg, 481 + (qrcodeImage.getWidth() - portraitImg.getWidth()) / 2, 1000 + (qrcodeImage.getHeight() - portraitImg.getHeight()) / 2, null); } font = font.deriveFont(22.0f); g2d.setFont(font); g2d.setColor(new Color(241, 66, 66)); FontMetrics fm = g2d.getFontMetrics(font); int textLength = fm.stringWidth("海草街提醒您"); g2d.drawString("海草街提醒您", 481 + (qrcodeImage.getWidth() - textLength) / 2, 1220); g2d.setColor(new Color(102, 102, 102)); fm = g2d.getFontMetrics(font); textLength = fm.stringWidth("长按识别二维码"); g2d.drawString("长按识别二维码", 481 + (qrcodeImage.getWidth() - textLength) / 2, 1255); g2d.dispose(); ByteArrayOutputStream aos = new ByteArrayOutputStream(); ImageIO.write(targetImg, "JPEG", aos); InputStream is = new ByteArrayInputStream(aos.toByteArray()); return is; } private static int[] computeCropPosition(BufferedImage source, int width, int height) { int[] cropParams = new int[4]; int owidth = source.getWidth(); int oheight = source.getHeight(); if (oheight * width - owidth * height > 0) { cropParams[0] = 0; cropParams[1] = (oheight - height) / 2; cropParams[2] = owidth; cropParams[3] = cropParams[2] * height / width; } else { cropParams[0] = (owidth - width) / 2; cropParams[1] = 0; cropParams[3] = oheight; cropParams[2] = cropParams[3] * width / height; } return cropParams; } public static BufferedImage crop(BufferedImage source, int startX, int startY, int w, int h) { int width = source.getWidth(); int height = source.getHeight(); if (startX <= -1) { startX = 0; } if (startY <= -1) { startY = 0; } if (w <= -1) { w = width - 1; } if (h <= -1) { h = height - 1; } BufferedImage result = new BufferedImage(w, h, source.getType()); for (int y = startY; y < h + startY; y++) { for (int x = startX; x < w + startX; x++) { int rgb = source.getRGB(x, y); result.setRGB(x - startX, y - startY, rgb); } } return result; } public static BufferedImage zoomInImage(BufferedImage originalImage, int width, int height) { int type = originalImage.getType(); if (type == 0) type = 5; BufferedImage newImage = new BufferedImage(width, height, type); Graphics g = newImage.getGraphics(); g.drawImage(originalImage, 0, 0, width, height, null); g.dispose(); return newImage; } // 邀请好友图片 public static void inviteFriendImg(InputStream urlInputStream, InputStream portraitInputStream, InputStream erCodeInputStream, String targetPath) throws IOException { inviteFriendImg(urlInputStream, portraitInputStream, erCodeInputStream, targetPath, 260, 908, 230); } /** * * @param urlInputStream * @param portraitInputStream * @param erCodeInputStream * @param targetPath * @param pX * -二维码的横坐标 * @param pY * -二维码的纵坐标 * @param size * -二维码的尺寸 * @throws IOException */ // 邀请好友图片 public static void inviteFriendImg(InputStream urlInputStream, InputStream portraitInputStream, InputStream erCodeInputStream, String targetPath, int pX, int pY, int size) throws IOException { BufferedImage bgImage = ImageIO.read(urlInputStream); final BufferedImage targetImg = new BufferedImage(bgImage.getWidth(), bgImage.getHeight(), BufferedImage.TYPE_INT_RGB); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  // 画 背景图片 final Graphics2D g2d = targetImg.createGraphics(); g2d.drawImage(bgImage, 0, 0, bgImage.getWidth(), bgImage.getHeight(), null); // 画 二维码 BufferedImage qrCodeImage = ImageIO.read(erCodeInputStream); qrCodeImage = ImageUtil.qrCodeImage(g2d, qrCodeImage, pX, pY, size, size); // 二维码长宽 // 230*230 // 画 头像 BufferedImage portraitImg = ImageIO.read(portraitInputStream); int portraitSize = size * 5 / 23; int pPX = pX + size / 2 - portraitSize / 2; int pPY = pY + size / 2 - portraitSize / 2; portraitImg = ImageUtil.portraitImg(g2d, portraitImg, pPX, pPY, portraitSize, portraitSize);// 头像长宽 OutputStream out = new FileOutputStream(new File(targetPath)); ImageIO.write(targetImg, "JPEG", out); out.flush(); out.close(); } // 二维码 public static BufferedImage qrCodeImage(Graphics2D g2d, BufferedImage originalImage, int pX, int pY, int width, int height) { g2d.drawImage(originalImage, pX, pY, width, height, null); return originalImage; } // 头像 public static BufferedImage portraitImg(Graphics2D g2d, BufferedImage originalImage, int pX, int pY, int width, int height) { g2d.drawImage(originalImage, pX, pY, width, height, null); return originalImage; } static BufferedImage roundImage(BufferedImage srcImage, int cornerRadius) { // 半径 int width = srcImage.getWidth(); int height = srcImage.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D gs = image.createGraphics(); HashMap mapH = new HashMap(); mapH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗锯齿 (抗锯齿总开关)   mapH.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);// 文字抗锯齿  gs.setRenderingHints(mapH); gs.setClip(new RoundRectangle2D.Double(0, 0, width, height, cornerRadius, cornerRadius)); gs.drawImage(srcImage, 0, 0, null); gs.dispose(); return image; } public static int saveToImgByInputStream(InputStream inputStream, String imgPath, String imgName) { int stateInt = 1; try { File file = new File(imgPath, imgName);// 可以是任何图片格式.jpg,.png等 FileOutputStream fos = new FileOutputStream(file); FileInputStream fis = (FileInputStream) inputStream; byte[] b = new byte[1024]; int nRead = 0; while ((nRead = fis.read(b)) != -1) { fos.write(b, 0, nRead); } fos.flush(); fos.close(); fis.close(); } catch (Exception e) { stateInt = 0; e.printStackTrace(); } finally { } return stateInt; } static int getTextLengthByWidth(Graphics2D g2d, Font font, String content, int maxWidth, int startPos) { FontMetrics fm = g2d.getFontMetrics(font); for (int i = startPos; i < content.length(); i++) { if (fm.stringWidth(content.substring(0, i)) >= maxWidth) return i + 1; } return content.length(); } public static int[] getImgWidthAndHeight(String imgUrl) throws MalformedURLException, IOException { if (StringUtil.isNullOrEmpty(imgUrl)) return new int[] { 0, 0 }; if (imgUrl.toLowerCase().endsWith("webp")) return getImgWidthAndHeightWithWebp(imgUrl); else return getImgWidthAndHeightWithPngAndJpg(imgUrl); } public static int[] getImgWidthAndHeightWithPngAndJpg(String imgUrl) throws MalformedURLException, IOException { InputStream murl = new URL(imgUrl).openStream(); BufferedImage sourceImg = ImageIO.read(murl); int width = sourceImg.getWidth(); int height = sourceImg.getHeight(); return new int[] { width, height }; } public static int[] getImgWidthAndHeightWithWebp(String imgUrl) throws MalformedURLException, IOException { String cacheFile = FileUtil.getCacheDir(); String targetPath = cacheFile + "/CACHE_DOWNLOAD_IMG_" + System.currentTimeMillis() + "_" + (long) (Math.random() * 1000000000L); HttpUtil.downloadFile(imgUrl, targetPath); FileInputStream file = new FileInputStream(targetPath); byte[] bytes = new byte[30]; file.read(bytes, 0, bytes.length); int width = ((int) bytes[27] & 0xff) << 8 | ((int) bytes[26] & 0xff); int height = ((int) bytes[29] & 0xff) << 8 | ((int) bytes[28] & 0xff); file.close(); return new int[] { width, height }; } }