8
头图
The article is continuously updated, you can follow the public programmer Alang or visit unread code blog .
This article Github.com/niumoo/JavaNotes has been included, welcome to Star.

Hello, everyone, I'm Alan.

It's already 2022. Recently, the mascot of the Beijing Winter Olympics, , , is very popular. It is said that one pier is hard to find, and all kinds of video news are overwhelmed. Programmers must have the way of programmers. Today, I will use Java to draw a ice dimple composed of characters for you. This article records the idea and process of generating character patterns.

Below is a bing pier pattern consisting of characters such as W@#&8*0. .

字符冰墩墩

1. Character pattern ideas

We all know that a digital picture is a two-dimensional image, which uses a two-dimensional array with a limit of to store the color information of each pixel , and the color information of these pixels is usually recorded in RGB mode. So in essence, our common picture is a two-dimensional array that stores pixel information.

像素图片 - 来自维基百科

Based on the above picture principles, we can find that if we want to convert a picture into a character pattern, we only need to convert the color information of each pixel into a certain character , so we can figure out that the picture is converted into The steps of the character pattern are as follows.

  1. Scale the image to the specified size, in order to ensure that the number of characters in the output is not too many.
  2. Traverse the pixels of the picture to get the color information of each pixel.
  3. According to the color information of the pixel, it is converted into grayscale (brightness) information.
  4. Convert the luminance information to the corresponding character.
  5. Output character pattern, that is, print a two-dimensional character array.

2. Image scaling

As mentioned above, since we want to convert the color information of each pixel into a certain character, if there are too many pixels, it will increase the restoration degree of the character picture, but it will look very troublesome, because so many characters you screen may not be displayed completely.

Therefore, we need to scale the picture first, scale it to a certain size, and then characterize it. Here, for convenience, the image processing method that comes with Java is directly used for image scaling. The following code examples are all scaling by specifying the width, and scaling after the height is calculated proportionally.

There are two main ways to resize an image in Java:

  1. Use java.awt.Graphics2D to resize the picture.
  2. Use Image.getScaledInstance to resize the picture.

2.1. java.awt.Graphics2D

Graphics2D is the basic class provided by the Java platform that can render two-dimensional shapes, texts, and images. The following is a simple example of using Graphics2D for image resizing.

/**
 * 图片缩放
 *
 * @param srcImagePath  图片路径
 * @param targetWidth   目标宽度
 * @return
 * @throws IOException
 */
public static BufferedImage resizeImage(String srcImagePath, int targetWidth) throws IOException {
    Image srcImage = ImageIO.read(new File(srcImagePath));
    int targetHeight = getTargetHeight(targetWidth, srcImage);
    BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics2D = resizedImage.createGraphics();
    graphics2D.drawImage(srcImage, 0, 0, targetWidth, targetHeight, null);
    graphics2D.dispose();
    return resizedImage;
}

/**
 * 根据指定宽度,计算等比例高度
 *
 * @param targetWidth   目标宽度
 * @param srcImage      图片信息
 * @return
 */
private static int getTargetHeight(int targetWidth, Image srcImage) {
    int targetHeight = srcImage.getHeight(null);
    if (targetWidth < srcImage.getWidth(null)) {
        targetHeight = Math.round((float)targetHeight / ((float)srcImage.getWidth(null) / (float)targetWidth));
    }
    return targetHeight;
}

The BufferedImage.TYPE_INT_RGB in the code represents the color model used, all the color models can be seen in the Java doc - Image document.

The resized picture can be saved in the following ways.

BufferedImage image = resizeImage("/Users/darcy/Downloads/bingdundun.jpeg", 200);
File file = new File("/Users/darcy/Downloads/bingdundun_resize.jpg");
ImageIO.write(image, "jpg", file);

The following is the effect of scaling the original 416 x 500 Bing Dung Dun image to 200 x 240.

Java 图片缩放

2.2. Image.getScaledInstance

This is another way to adjust the image size by Java native function. Using this method to adjust the image size is simple and convenient, the quality of the generated image is also good, and the code is relatively simple, but the of this method is not .

/**
 * 图片缩放
 *
 * @param srcImagePath  图片路径
 * @param targetWidth   目标宽度
 * @return
 * @throws IOException
 */
public static BufferedImage resizeImage2(String srcImagePath, int targetWidth) throws IOException {
    Image srcImage = ImageIO.read(new File(srcImagePath));
    int targetHeight = getTargetHeight(targetWidth, srcImage);
    Image image = srcImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_DEFAULT);
    BufferedImage bufferedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
    bufferedImage.getGraphics().drawImage(image, 0, 0, null);
    return bufferedImage;
}
// getTargetHeight 同 java.awt.Graphics2D 中示例代码

Image.SCALE_DEFAULT in the code represents the algorithm used for image scaling. You can view all available algorithms in the Java doc - Image document.

3. RGB grayscale calculation

We know that the picture is composed of pixels, and each pixel stores color information, usually RGB information, so we want to convert each pixel into a character, that is, the grayscale expression of the RGB information in the pixel Come out, different grayscales give different characters for representation.

For example, we divide the gray level into 10 levels, and each level selects a character for identification from high to low.

'W', '@', '#', '8', '&', '*', 'o', ':', '.', ' '

So how to perform grayscale calculation? At present, the common calculation methods include the average method, the weighted average method, and the gamma correction method. This is directly calculated using a mathematical formula similar to the gamma correction linear, which is also the method used by MATLAB , Pillow and OpenCV .

4. Output character picture

The preliminary preparations have been completed, we have scaled the picture, and we also know how to convert the RGB information on each pixel in the picture into a grayscale value, then we only need to traverse the RGB information of the scaled picture, Perform grayscale conversion, and then select the corresponding characters to print.

public static void main(String[] args) throws Exception {
    BufferedImage image = resizeImage("/Users/darcy/Downloads/bingdundun.jpeg", 150);
    printImage(image);
}

/**
 * 字符图片打印
 *
 * @param image
 * @throws IOException
 */
public static void printImage(BufferedImage image) throws IOException {
    final char[] PIXEL_CHAR_ARRAY = {'W', '@', '#', '8', '&', '*', 'o', ':', '.', ' '};
    int width = image.getWidth();
    int height = image.getHeight();
    for (int i = 0; i < height; i++) {
        for (int j = 0; j < width; j++) {
            int rgb = image.getRGB(j, i);
            Color color = new Color(rgb);
            int red = color.getRed();
            int green = color.getGreen();
            int blue = color.getBlue();
            // 一个用于计算RGB像素点灰度的公式
            Double grayscale = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
            double index = grayscale / (Math.ceil(255 / PIXEL_CHAR_ARRAY.length) + 0.5);
            System.out.print(PIXEL_CHAR_ARRAY[(int)(Math.floor(index))]);
        }
        System.out.println();
    }
}

// resizeImage 同第二部分代码

Here I choose a picture of Bingdundun, and you can see the effect after the output.

5. Other character pictures

The following are some other effects of image-to-character image conversion.

In 2022, the tiger is born with mighty character painting.

老虎字符画

Attack on Titan Character - Mikasa Character Drawing.

三笠字符画

As always, the code in the article is located at: github.com/niumoo/lab-notes

refer to

https://www.kdnuggets.com/2019/12/convert-rgb-image-grayscale.html

https://en.wikipedia.org/wiki/Grayscale

subscription

You can search for program ape Alang or visit Unread Code Blog to read.
This article Github.com/niumoo/JavaNotes has been included, welcome to Star.


程序猿阿朗
376 声望1.8k 粉丝

Hello world :)