如何用不到100行代码来创建程序艺术



如果您从未接触过生成艺术(生成艺术或程序艺术),您可能会吓scar它。 简而言之,这是一种艺术概念,它实际上是在创造自己,并且第一次不需要核心的编程知识。 所以我决定稍微稀释一下我们的磁带,他们开车了。

什么是生成艺术?


这是系统针对对象而不是人自己做出决定的结果。 如果系统具有规则和机会,那么它可以像单个Python程序一样简单。

通过编程,可以很容易地提出规则和限制。 有条件声明。 但是寻找使这些规则产生有趣效果的方法可能并不那么简单。


康威的生活游戏

Conway的生命游戏是一组著名的四个简单规则,它们定义了系统中每个单元的“出生”和“死亡”。 每条规则在每一代的系统升级中都起着作用。 尽管规则简单易懂,但很快就会出现复杂的模式,最终产生令人兴奋的结果。

这些规则可能为有趣的事情打下基础,但即使像康威的《人生游戏》一样令人兴奋的事情也是可以预见的。 这四个规则是每一代的决定因素。 因此,为了获得意外的结果,您需要在细胞的初始状态引入随机化。 从随机矩阵开始,每次执行都是唯一的,无需更改规则。

生成艺术的最好例子是那些发现可预测性和随机性相结合以创建有趣的东西的东西,这些东西在统计学上是不可能重复的。

为什么要尝试这个?


生成艺术并非总是您想要花费的时间。 但是,如果您决定进行此工作,那么可以依靠以下优势:

  • 经验。 生成艺术是磨练新旧技能的另一个机会。 它可以作为制定概念的输入,例如算法,数据结构,甚至是新语言。
  • 有形的结果。 在编程中,我们很少看到我们努力的实际结果。 好吧,或者至少我看不到它。 现在在我的客厅里,有几张海报上贴有我的程序艺术作品。 我喜欢通过代码完成此操作。
  • 有吸引力的设计。 每个人都有向某人解释个人项目的经验,甚至在面试过程中也是如此。 生成艺术不言自明。 即使他们不能完全理解这些方法,大多数人也会欣赏结果。

从哪里开始?


生成艺术入门与其他项目入门相同。 最重要的步骤是想出一个主意或找到进一步发展的主意。 一旦有了目标,就可以着手实现目标。

我的大部分创意项目都使用Python。 这是一种相当简单的语言,其中包含许多有助于图像处理的有用软件包。 例如, 枕头

幸运的是,您不必花太多时间从哪里开始-在下面,我将分享我的代码。

精灵生成器


当我看到一个包含用JavaScript编写的精灵生成器的帖子时,该项目开始了。 该程序创建了具有随机颜色选项的5×5像素艺术图片,其结果类似于多色空间入侵者。

我想用Python练习图像处理,所以我决定自己重新创建这个概念。 另外,我认为我可以扩展它,因为原始项目的精灵大小非常有限。 我不仅要指出精灵的大小,还要指出精灵的数量,甚至是图像的大小。

这是我程序的两个不同结果:


7x7-30–1900


43x43-6–1900

这两个图像彼此完全不同,但是它们都是同一系统的结果。 更不用说由于精灵的复杂性和随机生成的事实,即使有相同的论点,这些图像也很可能永远是其中一种。 我喜欢

环境环境


在熟悉Sprite生成器之前,您应该为工作做好准备。

如果您以前从未使用过Python,请下载Python 2.7.10 。 最初,我在设置环境时遇到问题,如果您也遇到这些问题,请在虚拟环境中查看。 并确保也安装了枕头

设置环境后,您可以将我的代码复制到扩展名为.py的文件中,然后运行以下命令:

python spritething.py [SPRITE_DIMENSIONS] [NUMBER] [IMAGE_SIZE] 

例如,创建子画面的第一个矩阵的命令为:

 python spritething.py 7 30 1900 

代号


 import PIL, random, sys from PIL import Image, ImageDraw origDimension = 1500 r = lambda: random.randint(50,215) rc = lambda: (r(), r(), r()) listSym = [] def create_square(border, draw, randColor, element, size): if (element == int(size/2)): draw.rectangle(border, randColor) elif (len(listSym) == element+1): draw.rectangle(border,listSym.pop()) else: listSym.append(randColor) draw.rectangle(border, randColor) def create_invader(border, draw, size): x0, y0, x1, y1 = border squareSize = (x1-x0)/size randColors = [rc(), rc(), rc(), (0,0,0), (0,0,0), (0,0,0)] i = 1 for y in range(0, size): I *= -1 element = 0 for x in range(0, size): topLeftX = x*squareSize + x0 topLeftY = y*squareSize + y0 botRightX = topLeftX + squareSize botRightY = topLeftY + squareSize create_square((topLeftX, topLeftY, botRightX, botRightY), draw, random.choice(randColors), element, size) if (element == int(size/2) or element == 0): I *= -1; element += I def main(size, invaders, imgSize): origDimension = imgSize origImage = Image.new('RGB', (origDimension, origDimension)) draw = ImageDraw.Draw(origImage) invaderSize = origDimension/invaders padding = invaderSize/size for x in range(0, invaders): for y in range(0, invaders): topLeftX = x*invaderSize + padding/2 topLeftY = y*invaderSize + padding/2 botRightX = topLeftX + invaderSize - padding botRightY = topLeftY + invaderSize - padding create_invader((topLeftX, topLeftY, botRightX, botRightY), draw, size) origImage.save(«Examples/Example-«+str(size)+»x»+str(size)+»-«+str(invaders)+»-«+str(imgSize)+».jpg») if __name__ == «__main__»: main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3])) 

这个解决方案还远远不够完美,但是它表明生成艺术的创作不需要大量的代码。 我将解释关键点。

主要功能始于创建原始图像并确定子画面的大小。 两个for循环负责确定每个sprite的边界,基本上将图像大小除以请求的sprite的数量。 这些值用于确定每个坐标。

看一下下面的图片。 假设四个正方形都是大小为1的精灵。传递给下一个函数的边框是指左上角和右下角的坐标。 因此,左上方精灵中的元组将为(0,0,1,1),而右上方精灵中的元组将为(1,0,2,1)。 它们将用作每个精灵的尺寸和基本坐标。


定义精灵边框的示例

create_invader函数定义精灵内每个正方形的边框。 确定边界的相同过程在此应用,并在下面介绍,仅使用完整的边界代替内部完整的图像来进行内部处理。 每个正方形的这些最终坐标将在下一个函数中用于绘制精灵。


3×3精灵击穿示例

为了确定颜色,使用三个随机RGB元组和三个黑色RGB元组的简单数组来模拟被绘制的机会为50%。 代码顶部的Lambda函数负责生成RGB值。

此功能的真正技巧是创建对称性。 每个正方形都与一个元素值相关联。 下图显示了元素的值在到达中心时如何增大,然后减小。 具有匹配元素值的正方形以相同的颜色显示。


7×7子画面中字符串的元素值和对称颜色

由于create_squarecreate_invader获取其参数,因此它使用队列和先前的元素值来确保对称。 首次出现值时,它们的颜色将放入队列中,而镜面正方形会删除这些颜色。


完成创建过程

我知道阅读别人对问题的解决方案和弯曲的代码有多么困难,但是我希望您能找到这个应用程序。 如果您完全放弃我的代码并找到完全不同的解决方案,那就太好了。

结论


生成艺术需要时间才能发挥其全部潜力。 一般而言,围绕生成的项目可能比生成艺术更多,这并不总是值得的。 但这很有趣,而且您永远都不知道它可以派上用场。

Source: https://habr.com/ru/post/zh-CN429078/


All Articles