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();
- }
- }
- }