java画海报

package study;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;

public class ImageUtil {

    /**
     * 颜色转换
     */
    private static Color fromStrToARGB(String str) {
        String str1 = str.substring(1, 3);
        String str2 = str.substring(3, 5);
        String str3 = str.substring(5, 7);
        int red = Integer.parseInt(str1, 16);
        int green = Integer.parseInt(str2, 16);
        int blue = Integer.parseInt(str3, 16);
        if (str.length() == 9) {
            String str4 = str.substring(7, 9);
            int alpha = Integer.parseInt(str4, 16);
            return new Color(red, green, blue, alpha);
        } else {
            return new Color(red, green, blue);
        }
    }

    /**
     * 创建Graphics2D
     *
     * @param bgBufImage 底图
     * @return Graphics2D
     */
    private static Graphics2D createG2D(BufferedImage bgBufImage) {
        Graphics2D bgBufImageGraphics = bgBufImage.createGraphics();
        bgBufImageGraphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        return bgBufImageGraphics;
    }

    /**
     * 绘制海报底色(默认微软雅黑/PLAIN/32)
     *
     * @param bgBufImage 底图
     * @param color      颜色
     */
    private static void setBackGroup(BufferedImage bgBufImage, String color) {
        Graphics2D bgBufImageGraphics = createG2D(bgBufImage);
        bgBufImageGraphics.setBackground(fromStrToARGB(color));// 填充整个屏幕
        bgBufImageGraphics.clearRect(0, 0, bgBufImage.getWidth(), bgBufImage.getHeight());
        bgBufImageGraphics.dispose();
    }

    /**
     * 绘制海报文字(默认微软雅黑/PLAIN/32)
     *
     * @param basebBI 底图
     * @param text    文本
     * @param x       坐标 x
     * @param y       坐标 y
     * @param color   颜色
     * @param font    字体
     */
    private static void drawText(BufferedImage basebBI, String text, int x, int y, String color, Font font) {
        // 抗锯齿
        if (font == null) {
            font = new Font("微软雅黑", Font.PLAIN, 32);
        }
        Graphics2D g2D = createG2D(basebBI);
        g2D.setFont(font);
        g2D.setPaint(new Color(0, 0, 0, 64));
        // 先绘制一遍底色
        g2D.drawString(text, x, y);
        g2D.setPaint(fromStrToARGB(color));
        // 再绘制一遍文字
        // 由于部分情况会出现文字模糊的情况,保险起见才出此对策。
        g2D.drawString(text, x, y);
        g2D.dispose();
    }

    /**
     * 
     * 绘制海报文字(换行)
     *
     * @param basebBI         底图
     * @param text            文本
     * @param x               位置:x
     * @param y               位置:y
     * @param lineHeight      单行行高
     * @param lineWidth       单行行宽
     * @param color           文本颜色
     * @param font            文本字体
     * @param limitLineNum    限制行数
     * @param backgroundWidth 底背位置(多行文字绘制时,出现为单行时居中的区域宽度。)
     */
    private static void drawTextNewLine(BufferedImage basebBI, String text, int x, int y, int lineHeight, int lineWidth,
            String color, Font font, int limitLineNum, int backgroundWidth) {
        Graphics2D graphics = createG2D(basebBI);
        if (font == null) {
            font = new Font("微软雅黑", Font.PLAIN, 32);
        }
        graphics.setFont(font);
        graphics.setPaint(fromStrToARGB(color));

        // 计算字符串所占屏幕长度
        FontRenderContext frc = graphics.getFontRenderContext();
        graphics.getFontRenderContext();
        // 记录行数
        List<String> lineList = new ArrayList<>();
        if (backgroundWidth > 0) {
            x = (backgroundWidth - lineWidth) / 2;
        }

        int stringIndex = 0;
        StringBuilder tmpLineString = new StringBuilder("");
        while (stringIndex < text.length()) {
            String tmp_char = text.substring(stringIndex, stringIndex + 1);
            Rectangle2D tempStringBounds = font.getStringBounds(tmpLineString + tmp_char, frc);
            double width = tempStringBounds.getWidth();
            if (width > lineWidth) {
                lineList.add(tmpLineString.toString());
                tmpLineString = new StringBuilder("");
            }
            tmpLineString = tmpLineString.append(tmp_char);
            stringIndex++;
        }
        // Color.BLACK 。字体颜色
        graphics.setPaint(fromStrToARGB(color));
        if (lineHeight == 0) {
            lineHeight = 35;
        }

        for (int i = 0; i < lineList.size(); i++) {
            String lineStr = lineList.get(i);
            double width = font.getStringBounds(lineStr, frc).getWidth();
            double diffWidth = font.getStringBounds("...", frc).getWidth();
            if (i > limitLineNum - 1) {
                break;
            } else if (i == limitLineNum - 1 && lineWidth - width < diffWidth) {
                lineStr = lineStr.substring(0, lineStr.length() - 2) + "...";
            }
            graphics.drawString(lineStr, x, y + (i + 1) * lineHeight);
            graphics.drawString(lineStr, x, y + (i + 1) * lineHeight);
        }
        graphics.dispose();
    }

    /**
     * 
     * 绘制海报图片
     *
     * @param basebBI 底图
     * @param path    图片地址
     * @param x       位置:x
     * @param y       位置:y
     * @param width   图片宽度
     * @param height  图片高度
     */
    private static void drawImage(BufferedImage basebBI, String path, int x, int y, int width, int height)
            throws Exception {
        BufferedImage qrCodeImage = ImageIO.read(new URL(path));
        drawImage(basebBI, qrCodeImage, x, y, width, height);
    }

    /**
     * 
     * 绘制海报图片
     *
     * @param basebBI 底图
     * @param imageBI 图片 BufferedImage
     * @param x       位置:x
     * @param y       位置:y
     * @param width   图片宽度
     * @param height  图片高度
     */
    private static void drawImage(BufferedImage basebBI, BufferedImage imageBI, int x, int y, int width, int height) {
        Graphics2D g2D = createG2D(basebBI);
        if (width == -1) {
            width = imageBI.getWidth();
        }

        if (height == -1) {
            height = imageBI.getHeight();
        }
        g2D.drawImage(imageBI, x, y, width, height, null);
        g2D.dispose();
    }

    /**
     * 创建带圆角的图片
     * 
     * @param path       图片地址
     * @param ratioWith  水平直径 -1 表示圆型
     * @param ratioHeith 垂直直径 -1 表示圆型
     */
    private static BufferedImage getRoundImage(String path, int ratioWith, int ratioHeith) throws Exception {
        BufferedImage qrCodeImage = ImageIO.read(new URL(path));
        BufferedImage image = new BufferedImage(qrCodeImage.getWidth(), qrCodeImage.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
        Graphics2D image2D = createG2D(image);
        if (ratioWith <= -1) {
            ratioWith = qrCodeImage.getWidth();
        }
        if (ratioHeith <= -1) {
            ratioHeith = qrCodeImage.getHeight();
        }
        image2D.fillRoundRect(0, 0, qrCodeImage.getWidth(), qrCodeImage.getHeight(), ratioWith, ratioHeith);
        image2D.setComposite(AlphaComposite.SrcIn);
        image2D.drawImage(qrCodeImage, 0, 0, qrCodeImage.getWidth(), qrCodeImage.getHeight(), null);
        image2D.dispose();
        return image;
    }

    /**
     * 输出图片
     * 
     * @param bgBufImage 底图
     * @param path       图片输出地址
     */
    private static void saveImage(BufferedImage bgBufImage, String path) throws Exception {
        Iterator<ImageWriter> iterator = ImageIO.getImageWritersByFormatName("jpeg");
        ImageWriter imageWriter = iterator.next();
        ImageWriteParam imageWriteParam = imageWriter.getDefaultWriteParam();
        imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        imageWriteParam.setCompressionQuality(1);
        imageWriter.setOutput(ImageIO.createImageOutputStream(new FileOutputStream(new File(path))));
        IIOImage iio_image = new IIOImage(bgBufImage, null, null);
        imageWriter.write(null, iio_image, imageWriteParam);
        imageWriter.dispose();
    }

    private static BufferedImage getFromUrl(String url) throws MalformedURLException, IOException {
        return ImageIO.read(new URL(url));
    }

    private static BufferedImage getFromPath(String path) throws MalformedURLException, IOException {
        return ImageIO.read(new FileInputStream(new File(path)));
    }

    public static void drawImage() throws Exception {
        // 二维码
        String headUrl = "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTL4BMa9N95tib3hae2XmIAhylV5Ex8GCekv0o6Rib55FLUvvnk1hMhBNZbqbUn5mXokt9DS7V2WSCkQ/132";
        // 头像
        String code = "e:\\1.jpg";

//        BufferedImage bgBufImage = new BufferedImage(750, 1334, BufferedImage.TYPE_INT_RGB);

//        setBackGroup(bgBufImage, "#FF0000");
//        drawImage(bgBufImage, qrCodeImageUrl, bgBufImage.getWidth() - 200, 10, -1, -1);
//        drawImage(bgBufImage, getRoundImage(headUrl, -1, -1), 100, 100, 200, 200);
//        drawText(bgBufImage, "测试", 0, 100, "#000000", null);
//        drawTextNewLine(bgBufImage, "测试圣诞快乐数据库里搭街坊卡拉手机打开拉萨奥斯陆冬季开发了喀什假大空立法解释考虑", 0, 100, 35, 200, "#000000", null, 3,
//                750);        

//        BufferedImage bgBufImage = ImageIO.read(new URL(headUrl));
//        drawText(bgBufImage, "测试", 0, 100, "#000000", null);
//        saveImage(bgBufImage, "E:\\demo1.jpeg");

        BufferedImage bgBufImage = getFromPath(code);
        BufferedImage headImage = getRoundImage(headUrl, 20, 20);
        drawImage(bgBufImage, headImage, 100, 100, 100, 100);
        saveImage(bgBufImage, "E:\\demo2.jpeg");
    }

    public static void main(String[] args) {
        try {
//            drawImage();
            String text = "LSG-XG-6-001";
            BufferedImage codeimg = getFromPath("e:\\11.png");
            BufferedImage bufImage = new BufferedImage(430, 430 + 30, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = bufImage.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setBackground(Color.white);
            g.setColor(Color.white);
            g.fillRect(0, 0, 430, 460);
            g.drawImage(codeimg, 0, 0, 430, 430, null);
            g.setColor(Color.red);
            Font font = new Font("微软雅黑", Font.BOLD, 40);
            g.setFont(font);
            // 居中显示
            FontMetrics fm = g.getFontMetrics(font);
            int textWidth = fm.stringWidth(text);
            int widthX = (430 - textWidth) / 2;
            g.drawString(text, widthX, 450);
            saveImage(bufImage, "E:\\demo2.jpeg");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

 

上一篇:文件二维码识别工具类 - java


下一篇:Java实现图片的镜像处理