Programmer's Romance: Thirty Lines of Code to Make a Picture in Her Name
Hello, everyone, everyone, there are many new friends reading this article, and there are probably many old friends. First of all, let me introduce myself. I am a gray ash, a senior porter in the code farming community; today Well, I don't have a teacher standing beside me, so I have to give you a one-mouth irrigation blog post.
The slogan of buy one get one free 520 promotions on the street is announcing the first special festival in early summer, but unfortunately, it was on the 5.21st that I found out that it was 520 again, and then another one. Look at the phone, damn it, it passed. . . I can't even kneel down on my mechanical keyboard that I bought at a huge cost of 200 oceans when I go home.
Hurry up to activate your brain up to 249IQ, think about what remedial measures are available, it is time to unlock the old human flesh reptile skills, and see if the friends who posted pictures in the ticket circle can provide a valuable flash of inspiration
Kung fu is ultimately rewarded, and sure enough, there is no gain; honestly, what kind of romantic work can a code farmer do?
- [ ] Write an html page and accompany her to watch the meteor shower
- [ ] Use her photos to create a PPT with music and auto-play
- [ ] A big screen in a black shopping mall, with her beautiful pictures Xiuxiu + I love you for ten thousand years
- [ ] AI automatically writes a Tibetan poem about
xxx 爱你一万年
- [ ] Write a no-interface APP, secretly install it on her mobile phone, and set a flower to pop up at regular intervals (horror pictures can also be used if you are not afraid of being beaten 🤭)
There are a lot of choices, and then there is a small question. Can the small gift of 5.20 be forgiven on 5.21? (Please see the beautiful girls here, feel your conscience, and tell me "can" in the comment area, okay)
Continuing from the above, even if there are many little fairies who tell me that they can, I can’t believe it if it makes sense. Next, I will share an idea worth 99 with the judges for free, and use her name to make a painting (below) , with such a large workload below, is it not normal to delay for a day or two (please tell me loudly, is it very witty)
Next, the old driver teaches you how to use thirty lines to draw her art painting with her (his and its) name
<!-- more -->
After writing so much, I still haven’t entered the topic. This article is so watered that I can’t read it myself😓, let’s get down to business.
1. Combat ideas
With the goal, the next step is to make a plan. Everyone knows that the computer world is composed of 0 and 1, so what is the picture world composed of?
I have heard the answer from the smart and witty friends, yes, yes, it is a pixel block with a color
So what are we going to do? The answer is ready to come out, young heroes and fairies, please tell me loudly, okay?
Cough cough, to be serious, just take this pixel block one by one, and then replace it with her (his and its) name.
2. Pre-war preparations
As the saying goes, the troops and horses are not moved, the food and grass go first, and some necessary preparations must be made before the official start.
[x] A beautiful and moving picture
- Process the background first to retain key character information and reduce noise
- For those who do not know ps, you can directly use https://www.remove.bg/zh to complete the cutout in three seconds
[x] Choose the technology stack to start, democratic choice
- java,
- php,
- golang,
- js,
- python?
In this case, we follow the voluntary principle and decide it's you -- Clawed Frog (JAVA)
3. go to war
Thank you for choosing java my natal skills, then let's see how to achieve our purpose
Steps to disassemble:
- read image
- and create an artboard of equal size
- Traverse each pixel of the image and read the RGB of the pixel
- Render text at the corresponding position on the artboard
- Save the artboard and you're done
Implementation source code:
public static Color int2color(int color) {
int a = (0xff000000 & color) >>> 24;
int r = (0x00ff0000 & color) >> 16;
int g = (0x0000ff00 & color) >> 8;
int b = (0x000000ff & color);
return new Color(r, g, b, a);
}
public void renderCharPhoto(String imgPath, String name, String saveFile) throws Exception {
// 第一步,载图片
BufferedImage img = ImageIO.read(new File(imgPath));
int w = img.getWidth(), h = img.getHeight();
// 第二步,创建等大的画板
BufferedImage output = new BufferedImage(w, h, img.getType());
Graphics2D g2d = output.createGraphics();
g2d.setFont(new Font("宋体", Font.PLAIN, 1));
int index = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
// 第三步,遍历每个像素点,并获取对应的rgb
char ch = name.charAt((index++) % name.length());
g2d.setColor(int2color(img.getRGB(x, y)));
// 第四步,写上他她它的名字
g2d.drawString(String.valueOf(ch), x, y);
}
}
// 第五步,保存图片
g2d.dispose();
ImageIO.write(output, "png", new File(saveFile));
}
It's that simple, just run and try the effect
There seems to be something wrong, this is no different from the original image, so what is the problem? The text on a pixel is invisible to my titanium alloy eyes. What can I do?
It makes sense. Enlarge the picture, isn't it ok? Then adjust the drawing board above, enlarge it 24 times, set the font size to 20, and leave some space between the words.
public void renderCharPhoto(String imgPath, String name, String saveFile) throws Exception {
BufferedImage img = ImageIO.read(new File(imgPath));
int w = img.getWidth(), h = img.getHeight();
BufferedImage output = new BufferedImage(w * 24, h * 24, img.getType());
Graphics2D g2d = output.createGraphics();
g2d.setFont(new Font("宋体", Font.PLAIN, 20));
int index = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
char ch = name.charAt((index++) % name.length());
g2d.setColor(int2color(img.getRGB(x, y)));
g2d.drawString(String.valueOf(ch), x * 24 + 2, y * 24 + 2);
}
}
g2d.dispose();
ImageIO.write(output, "png", new File(saveFile));
}
This standard Song Dynasty seems to reveal something. If you tell him (her) that it is hand-painted, can you believe it?
In order to be more realistic, try another hand-painted font, search online, and download one 潇洒手写体
https://www.diyiziti.com/Builder/446---d8230f9f1a6f17a4374b82f773ad83f1---resources
Then adjust the font settings in the above code
public void renderCharPhoto(String imgPath, String name, String saveFile) throws Exception {
BufferedImage img = ImageIO.read(new File(imgPath));
int w = img.getWidth(), h = img.getHeight();
BufferedImage output = new BufferedImage(w * 24, h * 24, img.getType());
Graphics2D g2d = output.createGraphics();
// 使用自定义的字体
try (InputStream inputStream = Files.newInputStream(Paths.get("D://MobileFile/潇洒手写体.ttf"))) {
Font font = Font.createFont(Font.TRUETYPE_FONT, inputStream);
g2d.setFont(font.deriveFont(Font.PLAIN, 20));
}
int index = 0;
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
char ch = name.charAt((index++) % name.length());
g2d.setColor(int2color(img.getRGB(x, y)));
g2d.drawString(String.valueOf(ch), x * 24 + 2, y * 24 + 2);
}
}
g2d.dispose();
ImageIO.write(output, "png", new File(saveFile));
}
What if the other person is familiar with your font?
There are also solutions. Search the app store for "character creation", and you can also create a unique font for yourself by the way.
Great, this time it feels impeccable, just find a print shop for the picture above, paint it, and you're done; take it away, thank you
If unfortunately, when you have a witty partner, then she/he/it will probably ask your soul, how do you do it, with the exact wording and spacing?
In the end, after talking about it for so long, I suddenly thought of a question, what does the 520 festival have to do with people like me who don't have female tickets?
4. Post-war benefits
The above thirty lines of code teach you how to implement a coax (Fuck) The method of female votes, the basic functions are still very complete, of course, I am so intimate, and I also provide you with a more friendly way, such as loading pictures and fonts directly from the Internet
public void testCharPicture() throws Exception {
prefix = "/tmp/";
String img = "http://hbimg.b0.upaiyun.com/2b79e7e15883d8f8bbae0b1d1efd6cf2c0c1ed1b10753-cusHEA_fw236";
ImgPixelWrapper.build()
.setSourceImg(img)
.setChars("小黄人")
// 字体文件下载地址: https://www.diyiziti.com/Builder/446
.setFontName("https://font.js.live/front/font/download?id=446")
.setBlockSize(24)
.setFontSize(22)
.setBgPredicate(color -> {
// 指定背景色,不渲染文本
if (color == 0) return true;
Color rc = ColorUtil.int2color(color);
// 将白色当作背景色
return rc.getRed() >= 245 && rc.getGreen() >= 245 && rc.getBlue() >= 245;
})
.setPixelType(PixelStyleEnum.CHAR_SEQ_SCALE_UP)
.build().asFile(prefix + "/char_pic_xhr.jpg");
System.out.println("---- over ---");
}
Corresponding source code: https://github.com/liuyueyi/quick-media
The introduction method is also very simple
<artifactId>image-plugin</artifactId>
<groupId>com.github.liuyueyi.media</groupId>
<version>2.6.4</version>
Is it very caring, is it very touching, should I like it, give a comment to support it, and add a favorite for the next time?
A grey contact
It is better to have no books than no books. The above content is purely from one family. Due to limited personal ability, there are unavoidable omissions and mistakes. If you find bugs or have better suggestions, you are welcome to criticize and correct them. Thank you very much.
- Personal site: https://blog.hhui.top
- Weibo address: Xiaohuihui Blog
- QQ: A gray gray / 3302797840
- WeChat public account: a gray blog
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。