JAVA生成LOVE字符图

这篇博客详细介绍了如何通过Java代码将图片转换为由字符组成的黑白字符图,以及带颜色的LOVE图案。作者利用图像的RGB值计算灰度,并映射到特定字符,以此创建出有序和无序的字符图像。代码中展示了如何控制字符的顺序打印,以展示图像的轮廓。
摘要由CSDN通过智能技术生成

先上原图:
请添加图片描述

转换后的黑白字符图:

请添加图片描述

带颜色的顺序love图(图中的字符顺序是LOVE的顺序):

请添加图片描述

带颜色的LOVE无序布满字符图:

请添加图片描述

带颜色的LOVE有序布满字符图:

请添加图片描述

代码实现:

public static void main(String[] args) throws Exception {
        // 使用字符来绘制图像的原理:(个人理解,可能不是很正确)
        // 就是把一张图片的每个像素点的rgb表示一个灰度值,使用这个灰度值来计算对应的字符位置
        // 顺序打印x轴y轴即可
        // 绘制的字符串内容
        String drawString = "love";
        // 用来控制灰度值是否使用空格字符来表示,当这个值大于字符串长度*255的时候,只会使用字符来显示图像中的黑色
        int density = 0;
        // 绘制的图片地址
        String imgPath = "C:\\tmp\\meme\\10_趣\\1.png";
        String targetPath = "C:\\tmp\\meme\\10_趣\\10.png";
        // pattern参数是用来控制是否顺序打印字符串内容,顺序打印字符一定要控制打印空白字符来填充,否则相同的字符排列就看不出图画的效果
        // true的时候取的是字符串中计算出来的对应的字符,这样即使没有填充空格,也能根据字符的不同来显示图片的轮廓,false的时候则是按照
        // 字符串中字符的顺序循环取,这样如果不填充空格,就看不出图片了(这种针对的是只有黑白两种颜色的情况,使用颜色来绘制的话一样能看出图片)
        // 代码中有输出到控制台,具体可以看对应的控制台输出
        characterPainting(drawString, density, imgPath, targetPath, false);
    }

    private static void characterPainting(String drawString, int density, String imgPath, String targetPath, boolean pattern) throws IOException {
        int baseLength = drawString.length();
        // 读取图片
        BufferedImage image = ImageIO.read(new File(imgPath));
        int width = image.getWidth();
        int height = image.getHeight();
        // 这个用来控制打印字符串中字符的索引位置
        int charIndex = 0;
        // 用来生成图片文件 11差不多是这个字体这个大小下所占用的像素大小
        BufferedImage bufferedImage = new BufferedImage(width * 11, height * 11, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        // 填充背景
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width * 11, height * 11);
        // 设置字体颜色 字体大小 字体
        graphics.setColor(Color.black);
        graphics.setFont(new Font("Consolas", Font.PLAIN, 16));

        for (int y = 0; y < height; y++) {
            // 拼接字符串(可以直接拼一行,画一行,也可以一个字符一个字符的画,以取到的rgb颜色来给字符增加颜色)
            StringBuilder line = new StringBuilder();
            for (int x = 0; x < width; x++) {
                // 获取图片对应坐标的rgb
                int rgb = image.getRGB(x, y);
                // 一个int是4个字节
                // 00000000 00000000(r) 00000000(g) 00000000(b) 获取对应的rgb只要移动对应的位数,并将高三位的置于0即可
                int r = rgb >> 16 & 0xff;
                int g = rgb >> 8 & 0xff;
                int b = rgb & 0xff;
                // 灰度值的计算方法,网上的,自己也可以顺便表示,但是用这个效果比较好
                int gray = Math.round(0.299f * r + 0.587f * g + 0.114f * b);
                // 计算一个比例,确定显示的字符的索引位置
                int index = gray * (baseLength + density) / 255;
                if (pattern) {
                    // true的时候,使用上面计算的字符串的索引位置
                    charIndex = index;
                }
                // 设置为当前取到的rgb
                graphics.setColor(new Color(r, g, b));
                // 计算绘制的坐标,y轴要+1,绘制字符时,y轴从0算的话,字符时绘制到画面以外的
                int drawX = x * 11;
                int drawY = (y + 1) * 11;
                // 超出字符串长度了,直接打印空格
                if (index >= baseLength) {
                    System.out.print(" ");
                    line.append(" ");
                    graphics.drawString(" ", drawX, drawY);
                } else {
                    // 打印对应的字符
                    char c = drawString.charAt(charIndex);
                    System.out.print(c);
                    charIndex = (charIndex + 1) % baseLength;
                    line.append(c);
                    graphics.drawString(c + "", drawX, drawY);
                }
            }
            System.out.println();
            // 直接一行一行的绘制,这种不能添加原图对应的颜色
//            graphics.drawString(line.toString(), 0, (y + 1) * 11);
        }
        ImageIO.write(bufferedImage, "png", new File(targetPath));
    }
05-22 186
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dichotomy_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值