package com.hkb.soulaud.tools; import com.hkb.soulaud.pojo.ActivityPlayerPoster; import com.hkb.soulaud.pojo.ActivityPoster; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.Ellipse2D; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.IOException; / * @author lime * @Description * @Date 10:41 2020/3/31 * @Modified by 海报图片生成工具 */ @Slf4j public class PosterImageTools {
public static BufferedImage circle(BufferedImage avatarImage) throws IOException {
int width = 90; // 透明底的图片 BufferedImage formatAvatarImage = new BufferedImage(width, width, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D graphics = formatAvatarImage.createGraphics(); //把图片切成一个圓 {
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //留一个像素的空白区域,这个很重要,画圆的时候把这个覆盖 int border = 1; //图片是一个圆型 Ellipse2D.Double shape = new Ellipse2D.Double(border, border, width - border * 2, width - border * 2); //需要保留的区域 graphics.setClip(shape); graphics.drawImage(avatarImage, border, border, width - border * 2, width - border * 2, null); graphics.dispose(); } //在圆图外面再画一个圆 {
//新创建一个graphics,这样画的圆不会有锯齿 graphics = formatAvatarImage.createGraphics(); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int border = 3; //画笔是4.5个像素,BasicStroke的使用可以查看下面的参考文档 //使画笔时基本会像外延伸一定像素,具体可以自己使用的时候测试 Stroke s = new BasicStroke(4.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); graphics.setStroke(s); graphics.setColor(Color.WHITE); graphics.drawOval(border, border, width - border * 2, width - border * 2); graphics.dispose(); } return formatAvatarImage; } / * 传入的图像必须是正方形的 才会 圆形 如果是长方形的比例则会变成椭圆的 * <p> * 用户头像地址 * * @return * @throws IOException */ public static BufferedImage convertCircular(BufferedImage bi1) throws IOException {
BufferedImage formatAvatarImage = new BufferedImage(bi1.getWidth() + 10, bi1.getHeight() + 10, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D graphics = formatAvatarImage.createGraphics(); 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.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2.setClip(shape); // 使用 setRenderingHint 设置抗锯齿 g2.drawImage(bi1, 0, 0, null); // 设置颜色 g2.setBackground(Color.green); g2.dispose(); int border = 3; //画笔是4.5个像素,BasicStroke的使用可以查看下面的参考文档 //使画笔时基本会像外延伸一定像素,具体可以自己使用的时候测试 Stroke s = new BasicStroke(4.5F, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); graphics.setStroke(s); graphics.setColor(Color.WHITE); graphics.drawOval(border, border, (bi1.getWidth() + 10) - border * 2, (bi1.getWidth() + 10) - border * 2); graphics.dispose(); return bi2; } public static void playerPoster(ActivityPlayerPoster poster) throws IOException {
BufferedImage bgImage = fileToBufferedImage(poster.getBgPath()); BufferedImage qrImage = fileToBufferedImage(poster.getQrUrl()); BufferedImage playerImage = fileToBufferedImage(poster.getCoverPath()); playerImage = circle(playerImage); Graphics2D graphics2D = bgImage.createGraphics(); //消除锯齿 graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); //在背景上绘制二维码 graphics2D.drawImage(qrImage, 36, 294, 56, 56, null); //在背景上绘制选手头像 graphics2D.drawImage(playerImage, 90, 115, 90, 90, null); Font font = new Font("SourceHanSerifCN-Bold", Font.PLAIN, 10); //绘制编号 graphics2D.setFont(font); //正文颜色 graphics2D.setPaint(new Color(255, 255, 255)); graphics2D.drawString("编号:" + poster.getNumber(), 197, 32); //绘制活动标题 Font title1Font = new Font("SourceHanSerifCN-Bold", Font.PLAIN, 14); graphics2D.setFont(title1Font); graphics2D.setPaint(new Color(255, 191, 0)); //计算居中 FontMetrics fm = graphics2D.getFontMetrics(title1Font); int title1Center = (bgImage.getWidth() - fm.stringWidth(poster.getTitle1())) / 2; graphics2D.drawString(poster.getTitle1(), title1Center, 70); graphics2D.setPaint(new Color(255, 191, 0)); int title2Center = (bgImage.getWidth() - fm.stringWidth(poster.getTitle2())) / 2; graphics2D.drawString(poster.getTitle2(), title2Center, 90); //绘制选手名称 graphics2D.setPaint(new Color(255, 255, 255)); Font playerNameFont = new Font("SourceHanSerifCN-Bold", Font.PLAIN, 12); graphics2D.setFont(playerNameFont); graphics2D.drawString("选手名称:" + poster.getPlayerName(), 36, 240); graphics2D.setPaint(new Color(255, 255, 255)); //绘制机构名称 graphics2D.drawString("单位机构:" + poster.getMechanismName(), 36, 260); graphics2D.setPaint(new Color(255, 255, 255)); //绘制二维码右边的文字 graphics2D.setPaint(new Color(255, 191, 0)); graphics2D.drawString("长按识别二维码", 100, 310); graphics2D.setPaint(new Color(255, 191, 0)); graphics2D.drawString("为支持的选手打CALL!", 100, 330); graphics2D.setPaint(new Color(255, 191, 0)); //释放图形上下文 graphics2D.dispose(); File posterFile = new File(poster.getUploadPath() + poster.getPosterName()); log.debug(posterFile + ""); ImageIO.write(bgImage, "png", posterFile); } 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); gs.dispose(); return image; } / * 设置圆角 * * @param srcImage 图片 * @param radius 圆角 * @param border 边框 * @param padding 内边距 */ public static BufferedImage setRadius(BufferedImage srcImage, int radius, int border, int padding) throws IOException {
int width = srcImage.getWidth(); int height = srcImage.getHeight(); int canvasWidth = width + padding * 2; int canvasHeight = height + padding * 2; BufferedImage image = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D gs = image.createGraphics(); gs.setComposite(AlphaComposite.Src); gs.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gs.setColor(Color.WHITE); gs.fill(new RoundRectangle2D.Float(0, 0, canvasWidth, canvasHeight, radius, radius)); gs.setComposite(AlphaComposite.SrcAtop); gs.drawImage(setClip(srcImage, radius), padding, padding, null); if (border != 0) {
gs.setColor(Color.GRAY); gs.setStroke(new BasicStroke(border)); gs.drawRoundRect(padding, padding, canvasWidth - 2 * padding, canvasHeight - 2 * padding, radius, radius); } gs.dispose(); return image; } / * 圆角 */ public static BufferedImage setRadius(BufferedImage srcImage) throws IOException {
int radius = (srcImage.getWidth() + srcImage.getHeight()) / 25; return setRadius(srcImage, radius, 0, 0); } / * 圆形 */ public static BufferedImage setRadius2(BufferedImage srcImage) throws IOException {
int radius = (srcImage.getWidth() + srcImage.getHeight()) / 2; return setRadius(srcImage, radius, 0, 0); } public static BufferedImage fileToBufferedImage(String filePath) throws IOException {
File file = new File(filePath); FileInputStream fis = new FileInputStream(file); BufferedImage image = ImageIO.read(fis); fis.close(); return image; } public static void activityPoster(ActivityPoster poster) throws Exception {
BufferedImage bgImage = fileToBufferedImage(poster.getBgPath()); BufferedImage acImage = fileToBufferedImage(poster.getCoverPath()); //等宽高缩放图片 acImage = ImageTools.zoomImage(acImage, 440, 200); acImage = setRadius(acImage); BufferedImage qrImage = fileToBufferedImage(poster.getQrUrl()); qrImage = setRadius(qrImage); Graphics2D graphics2D = bgImage.createGraphics(); //消除锯齿 graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); //在背景上绘制活动封面 graphics2D.drawImage(acImage, 24 * 2, 80 * 2, 221 * 2, 99 * 2, null); //在背景上绘制二维码 graphics2D.drawImage(qrImage, 200, 505, 140, 140, null); //绘制活动标题 Font title1Font = new Font("SourceHanSerifCN-Bold", 1, 14 * 2); graphics2D.setFont(title1Font); graphics2D.setPaint(new Color(255, 191, 0)); //计算居中 FontMetrics fm = graphics2D.getFontMetrics(title1Font); int title1Center = (bgImage.getWidth() - fm.stringWidth(poster.getTitle1())) / 2; graphics2D.drawString(poster.getTitle1(), title1Center, 50 * 2); graphics2D.setPaint(new Color(255, 191, 0)); int title2Center = (bgImage.getWidth() - fm.stringWidth(poster.getTitle())) / 2; graphics2D.drawString(poster.getTitle2(), title2Center, 70 * 2); //绘制二维码右边的文字 Font qrTopInfoFont = new Font("SourceHanSerifCN-Bold", 1, 12 * 2); FontMetrics fm2 = graphics2D.getFontMetrics(qrTopInfoFont); int qrTopInfoCenter = (bgImage.getWidth() - fm2.stringWidth(poster.getQrInfo1())) / 2; graphics2D.setFont(qrTopInfoFont); graphics2D.drawString(poster.getQrInfo1(), qrTopInfoCenter, 210 * 2); graphics2D.setPaint(new Color(255, 191, 0)); int qrTopInfo2Center = (bgImage.getWidth() - fm2.stringWidth(poster.getQrInfo2())) / 2; graphics2D.drawString(poster.getQrInfo2(), qrTopInfo2Center, 230 * 2); graphics2D.setPaint(new Color(255, 191, 0)); //释放图形上下文 graphics2D.dispose(); File posterFile = new File(poster.getUploadPath() + poster.getPosterName()); log.debug(posterFile + ""); ImageIO.write(bgImage, "png", posterFile); } }
讯享网

讯享网 public static String generateCover(UploadConfig uploadConfig, InputStream coverTemplateInputStream, String city, String title) throws IOException {
BufferedImage bg = ImageIO.read(coverTemplateInputStream); Graphics2D graphics2D = bg.createGraphics(); int cityFontW = 50; //绘制城市 Font cityFont = new Font("黑体", Font.PLAIN, cityFontW); graphics2D.setFont(cityFont); graphics2D.setPaint(new Color(250, 252, 255)); graphics2D.drawString(city, 50, 300); //绘制活动标题 int fontW = 100; //所有字总宽度 int allFontW = 100 * title.length(); Font title1Font = new Font("华康黑体W9(P)", Font.PLAIN, fontW); graphics2D.setFont(title1Font); graphics2D.setPaint(new Color(250, 252, 255)); //消除锯齿 graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); //计算居中 x int title1Center = (bg.getWidth() - allFontW) / 2; graphics2D.drawString(title, title1Center, 441); graphics2D.shear(0.1, -0.4); //释放图形上下文 graphics2D.dispose(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bg, "jpg", byteArrayOutputStream); byteArrayOutputStream.flush(); InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); return AliOssTools.upload(inputStream, "jpg", uploadConfig); }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/72364.html