如何用代码画出一幅好看的画

Posted 阎楠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用代码画出一幅好看的画相关的知识,希望对你有一定的参考价值。

前言

随着计算机技术的逐步发展,借助计算机强大的能力进行绘画操作,已经变得非常容易。绘画作品的水平也是越来越高,下面就来看看用编程语言绘画,能搞出什么有意思的东西,相比人类的创作又有哪些值得我们思考的地方。

绘画

用代码输出类似绘画的内容,最最原始的恐怕就是直接使用 print 函数了。

print 输出字符

def do_print():
    print('''

        へ     /|
      /\7    ∠_/
      / │   / /
     │ Z _,< /   /`ヽ
     │     ヽ   /  〉
      Y     `  /  /
     イ● 、 ●  ⊂⊃〈  /
     ()  へ    | \〈
      >ー 、_  ィ  │ //
      / へ   / ノ<| \\
      ヽ_ノ  (_/  │//
      7       |/
      >―r ̄ ̄`ー―_
     ''')

这个方法执行后,就可以在控制台看到下面这幅可爱的皮卡丘画了。

这种做法,可以说是完全没有什么技术水平了。想要画什么内容,还得预先编排字符,太麻烦了。于是便有了升级版。

图片转字符

这种用图片转字符,看似没有什么意义,但其实有时候可以创作出意想不到的作品。比如前一阵子的顶流冰墩墩。

这种做法的思路总的来说,就是把图片的抽样图片的像素信息,然后将像素信息中关键的亮度信息用特殊的字符串进行打印,效果就是我们最终看到的样子。

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

更多具体实现可以参考 字符作画,我用字符画个冰墩墩

使用 Python-turtle 库作图

下面这几幅知乎用户的回答,可以说是非常有水平了。

import random
import turtle
from turtle import *

t = turtle.Turtle()
w = turtle.Screen()


def tree(branchLen, t):
    if branchLen > 3:
        if 8 <= branchLen <= 12:
            if random.randint(0, 2) == 0:
                t.color('snow')
            else:
                t.color('lightcoral')
            t.pensize(branchLen / 3)
        elif branchLen < 8:
            if random.randint(0, 1) == 0:
                t.color('snow')
            else:
                t.color('lightcoral')
            t.pensize(branchLen / 2)
        else:
            t.color('sienna')
            t.pensize(branchLen / 10)

        t.forward(branchLen)
        a = 1.5 * random.random()
        t.right(20 * a)
        b = 1.5 * random.random()
        tree(branchLen - 10 * b, t)
        t.left(40 * a)
        tree(branchLen - 10 * b, t)
        t.right(20 * a)
        t.up()
        t.backward(branchLen)
        t.down()


def petal(m, t):  # 树下花瓣
    for i in range(m):
        a = 200 - 400 * random.random()
        b = 10 - 20 * random.random()
        t.up()
        t.forward(b)
        t.left(90)
        t.forward(a)
        t.down()
        t.color("lightcoral")
        t.circle(1)
        t.up()
        t.backward(a)
        t.right(90)
        t.backward(b)


def main():
    t = turtle.Turtle()
    myWin = turtle.Screen()
    getscreen().tracer(5, 0)
    turtle.screensize(bg='wheat')
    t.left(90)
    t.up()
    t.backward(150)
    t.down()
    t.color('sienna')
    tree(60, t)
    petal(100, t)

    myWin.exitonclick()


if __name__ == '__main__':
    main()


可以看到,使用 turtle 库加上强大的数学几何知识,可以创作出非常好的看图像。更多内容可以参考 这个问题

使用 AI 作画

ERNIE-ViLG文生图

使用以上方案绘制的内容,一般都比较刻板,缺少一些人文气息。少了一些人类才能有的特点。但是随着 AI 算力的提升和大数据的逐步发展,已经有很多可以使用 AI 进行作画的平台了。 比如 百度飞浆文心大模型 ERNIE-ViLG文生图 平台。

import wenxin_api
from wenxin_api.tasks.text_to_image import TextToImage
import secret


def draw(t, s):
    wenxin_api.ak = secret.ak
    wenxin_api.sk = secret.sk
    input_dict = 
        "text": t,
        "style": s
    
    rst = TextToImage.create(**input_dict)
    print(rst)


if __name__ == '__main__':
    text = "夏天"
    style = "油画"
    draw(text, style)

使用上面的代码,就可以创作出 油画 风格的夏天,可以看看 AI 生成结果。

2022-08-28 12:20:06,785 - model is painting now!, 
- taskId: 1062408, waiting: 30s
'imgUrls': ['https://image.cha138.com/20221017/90646a16e59448548690dfc79073292d.jpg', 'https://image.cha138.com/20221017/72ae69e985614cfbbef641b9ebff0a3b.jpg', 'https://image.cha138.com/20221017/8cf541e510fb4c9b91776b0b5836eaa1.jpg', 'https://image.cha138.com/20221017/bc05a89130994918813c49e96e67003a.jpg', 'https://image.cha138.com/20221017/cc3a234d18c34f21bfe939ca2ac0b151.jpg', 'https://image.cha138.com/20221017/f595a58b28134dc999c941aafdd0ce95.jpg']

可以看到速度还是很快的出不多一分钟就搞定了。可以预览一下结果






可以看到还是很厉害了,水平应可以赶上专科院校的毕业生了,但是作画速度那可是降维打击啊。

使用 ERNIe-ViLG 搭配自定义的关键字可以生成 水彩、油画、粉笔画、卡通、蜡笔画、儿童画等多种风格的图片。

可以再试一下水彩画风格的天龙八部






是不是还挺有感觉的。

DALL·E 2

当然,说到 AI 绘画,国外大公司也有很厉害的。比如 OpenAI 公司DALL·E 2

比如以写实风格创作一个宇航员骑着一匹马的图像

在换个铅笔画风格的

使用 DALL·E 2 可以根据创作风格,更多关键字由 AI 创作出非常有想象力的作品。可以到 DALL·E 2 的主页查看更多更详细的内容。

总结

其实用代码直接绘制图形,还有很多其他方案。比如大名鼎鼎的 MATLAB ,可以创作出非常精良的数学几何图形。

但是比较一下上面的这几种方案,可以说 AI 作画的水平,一下子提升了好几个层次。创作需要的输入越来越明确,越来越简答,越发的人性化。但是输出的内容,却越发的开始接近甚至超越了人类的水平。

参考文档

以上是关于如何用代码画出一幅好看的画的主要内容,如果未能解决你的问题,请参考以下文章

如何用代码画出一幅好看的画

神级程序员教你如何用四行代码画出一幅中国地图!Python就是牛逼

如何用ProcessOn画出漂亮的思维导图

如何用Matlab画出一组坐标点,并且将这组坐标点按照X坐标从小到大的顺序连线,

简单的线条不简单的画

请问如何用matlab画出一个三维的正方体?