Java艺术字图片生成

/**
 * 艺术字图片生成工具
 * @author visy.wang
 * @date 2021/12/8 10:31
 */
public class ImageUtil {
        private static final String FONT_FILE_PATH = "font/FZXBS_GBK.TTF"; //字体文件路径
        private static final float FONT_SIZE = 140f; //字号
        private static final java.awt.Color COLOR = java.awt.Color.RED; //颜色
        private static Font fontPlain; //正常字体
        private static Font fontBold; //加粗字体

        public static Boolean enableTest = false; //测试启用开关

        static {
            try{
                //字体加载以及设置
                Resource fontResource = new ClassPathResource(FONT_FILE_PATH);
                InputStream inputStream = fontResource.getInputStream();
                Font f = Font.createFont(Font.TRUETYPE_FONT, inputStream);
                fontPlain = f.deriveFont(Font.PLAIN, FONT_SIZE);

                Map<TextAttribute, Object> attrs = new HashMap<>();
                attrs.put(TextAttribute.SIZE, FONT_SIZE);
                attrs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_DEMIBOLD);
                fontBold = f.deriveFont(attrs);
            }catch (IOException | FontFormatException e){
                e.printStackTrace();
            }
        }

        /**
         * 文字转艺术字图片
         * @param text 文本内容
         * @param width 宽度
         * @param width 高度
         * @param padding 两端间隔
         * @param isBold 是否加粗
         * @return 图片
         */
        public static BufferedImage toImage(String text, int width, int height, int padding, Boolean isBold) {
            int wordWidth = (width-padding*2) / text.length();

            Font font = isBold ? fontBold : fontPlain;

            // 生成图片
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = bufferedImage.createGraphics();
            // 白色背景
            g2d.setColor(java.awt.Color.white);
            // 填充矩形
            g2d.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());

            //消除锯齿
            antialiasing(g2d);

            char[] chars = text.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                String ch = String.valueOf(chars[i]);
                BufferedImage bi = textToImage(ch, font, wordWidth, height , i);

                //测试
                printWord(bi, "afterResizeImage", i);

                g2d.drawImage(bi, i * bi.getWidth()+padding, -bi.getHeight() / 12, bi.getWidth(), bi.getHeight(), null);
            }
            g2d.dispose();

            return cutout(bufferedImage);
        }

        /**
         * 文字转图片
         * @param string 文字
         * @param font 字体
         * @param wordWidth 单个文字宽度
         * @param height 高度
         */
        private static BufferedImage textToImage(String string, Font font, int wordWidth, int height, int i){
            BufferedImage bufferedImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
            Graphics2D tempG2 = (Graphics2D) bufferedImage.getGraphics();
            Rectangle2D r2d = font.getStringBounds(string, tempG2.getFontRenderContext());
            // 生成文字大小的ARGB图片,纠正部分艺术字高度测量误差
            BufferedImage bi = new BufferedImage((int) r2d.getWidth(), (int) (r2d.getHeight()/5*6), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = (Graphics2D) bi.getGraphics();
            bi = g2d.getDeviceConfiguration().createCompatibleImage(bi.getWidth(), bi.getHeight(), Transparency.TRANSLUCENT);
            g2d.dispose();
            g2d = (Graphics2D) bi.getGraphics();
            g2d.setFont(font);
            g2d.setColor(COLOR);
            g2d.setBackground(java.awt.Color.WHITE);

            //消除锯齿
            antialiasing(g2d);

            g2d.drawString(string, 0, font.getSize() - 1);
            g2d.dispose();

            //测试
            printWord(bi, "afterTextToImage", i);

            bi = resizeImage(bi, wordWidth, height);

            return bi;
        }

        /**
         * 重置图片大小
         * @param oldImage 原图
         * @param w 新宽度
         * @param h 新高度
         * @return 新图片
         */
        private static BufferedImage resizeImage( BufferedImage oldImage, int w, int h) {
            BufferedImage newImage = new BufferedImage(w, h, oldImage.getType());
            Graphics2D g2d = newImage.createGraphics();
            //消除锯齿
            antialiasing(g2d);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.drawImage(oldImage, 0, 0, w, h, null);
            g2d.dispose();
            return newImage;
        }

        /**
         * 去掉背景色
         * @param bi 原图片
         * @return 去掉背景色的图片
         */
        private static BufferedImage cutout(BufferedImage bi) {
            BufferedImage image = new BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
            Graphics2D g2d = image.createGraphics();
            //消除锯齿
            antialiasing(g2d);
            g2d.drawImage(bi, 0, 0, null);
            g2d.dispose();
            int width = image.getWidth();
            int height = image.getHeight();
            DirectColorModel dcm = (DirectColorModel) ColorModel.getRGBdefault();
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    int rgb = image.getRGB(x, y);
                    int red = dcm.getRed(rgb);
                    int green = dcm.getGreen(rgb);
                    int blue = dcm.getBlue(rgb);
                    int alp = dcm.getAlpha(rgb);
                    if (red == 0 && blue == 0 && green == 0) {// 如果像素为黑,则让它透明
                        alp = 0;
                        rgb = alp << 24 | 0 << 16 | 0 << 8 | 0;// 进行标准ARGB输出以实现图象过滤
                        image.setRGB(x, y, rgb);
                    }
                    if (red == 255 && blue == 255 && green == 255) {// 如果像素为白色,则让它透明
                        alp = 0;
                        rgb = alp << 24 | 0 << 16 | 0 << 8 | 0;// 进行标准ARGB输出以实现图象过滤
                        image.setRGB(x, y, rgb);
                    }
                }
            }
            return image;
        }

        //消除锯齿
        private static void antialiasing(Graphics2D g2d){
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        }

        //测试用
        private static void printWord(BufferedImage bi, String name, int i){
            if(!enableTest){
                return;
            }
            try{
                ImageIO.write(bi, "png", new File("D:\\test\\words\\"+name+i+".png"));
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值