前言
随着计算机技术的逐步发展,借助计算机强大的能力进行绘画操作,已经变得非常容易。绘画作品的水平也是越来越高,下面就来看看用编程语言绘画,能搞出什么有意思的东西,相比人类的创作又有哪些值得我们思考的地方。
绘画
用代码输出类似绘画的内容,最最原始的恐怕就是直接使用 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 randomimport turtlefrom 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_apifrom wenxin_api.tasks.text_to_image import TextToImageimport secretdef 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://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fex', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fi4', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828f5q', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828f30', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fv9', 'https://wenxin.baidu.com/younger/file/ERNIE-ViLG/89df26b9853d837d331d626ffa62828fa2']}
可以看到速度还是很快的出不多一分钟就搞定了。可以预览一下结果
可以看到还是很厉害了,水平应可以赶上专科院校的毕业生了,但是作画速度那可是降维打击啊。
使用 ERNIe-ViLG 搭配自定义的关键字可以生成 水彩、油画、粉笔画、卡通、蜡笔画、儿童画等多种风格的图片。
可以再试一下水彩画风格的天龙八部 。
是不是还挺有感觉的。
DALL·E 2
当然,说到 AI 绘画,国外大公司也有很厉害的。比如 OpenAI 公司 的 DALL·E 2 。
比如以写实风格创作一个宇航员骑着一匹马的图像
在换个铅笔画风格的
使用 DALL·E 2 可以根据创作风格,更多关键字由 AI 创作出非常有想象力的作品。可以到 DALL·E 2 的主页查看更多更详细的内容。
总结
其实用代码直接绘制图形,还有很多其他方案。比如大名鼎鼎的 MATLAB ,可以创作出非常精良的数学几何图形。
但是比较一下上面的这几种方案,可以说 AI 作画的水平,一下子提升了好几个层次。创作需要的输入越来越明确,越来越简答,越发的人性化。但是输出的内容,却越发的开始接近甚至超越了人类的水平。