Python 的标准库没有附带任何功能强大的图像处理代码,但有一些易于安装和使用的替代方案。我将展示如何使用PIL做到这一点。
from PIL import Image
def randomStars(small, large):
import random
filename = pickAFile()
pic = Image.open(filename)
max_x, max_y = pic.size
pixels = im.load()
x = random.randrange(max_x)
y = random.randrange(max_y)
for i in range(max_x):
for j in range(max_y):
if random.random() < 0.25:
red = random.randint(256)
green = random.randint(256)
blue = random.randint(256)
pixels[i, j] = (red, green, blue, 1)
im.show()
该show
函数不会在您的应用程序中显示图像(为此,您需要某种带有事件循环的 GUI,例如tkinter
or PySide
);它将文件保存到临时目录并运行特定于平台的程序(如 Preview 或 xv)来显示它。
我假设您还想保存文件。这也很容易:
name, ext = os.path.splitext(filename)
outfilename = '{}-with-stars.{}'.format(name, ext)
im.save(outfilename)
这会将其保存回具有默认 JPEG 设置的 .jpg,依赖于 PIL 从文件名中猜测您想要的内容。(这意味着,是的,您可以使用 . 将其保存为 PNG '{}-with-stars.png'.format(name)
。)如果您想要更多控制,PIL 也可以这样做,指定明确的格式和特定于格式的选项。
到目前为止,这只是如何将您现有的代码变成可以工作的东西,您可以使用它并开始调试;它实际上并没有回答原来的问题。
我想编写一个函数,它将在这张照片的天空中创建一个随机数(在 m 和 n 之间,包括在内)的星星
所以首先,你需要这个作为你的循环,而不是所有像素的循环:
for _ in random.randint(m, n):
现在:
我希望星星应该由单个白色像素或由 4 个相邻白色像素组成的正方形随机组成。
x, y = random.randrange(max_x), random.randrange(max_y)
if random.random() < .5:
# draw white pixel at [x, y]
pixels[x, y] = (1, 1, 1, 1)
else:
# draw square at [x, y], making sure to handle edges
我也不想在树枝、月亮或鸟上放置一个“星星”(1 像素)
您需要定义如何知道树枝、月亮或鸟的一部分。你能用像素颜色来定义吗?
乍一看,您似乎可以做到。月亮的像素比其他任何东西都更亮、更饱和、更偏红等(除了角落的AP标志,它更亮)。鸟和树枝比其他任何东西都更黑。事实上,它们是如此不同,以至于您甚至不必担心进行正确的色彩空间数学;它可能像这样简单:
r, g, b, a = pixels[x, y]
fake_brightness = r+g+b+a
if fake_brightness < 0.2:
# Tree or bird, pick a new random position
elif 1.2 < fake_brightness < 2.8:
# Moon, pick a new random position
else:
# Sky or API logo, scribble away
(这些数字显然只是凭空捏造的,但经过一些试验和错误,应该可以为您提供可用的值。)
当然,如果您将此作为学习练习,您可能想学习正确的色彩空间数学,甚至可能编写一个边缘检测算法,而不是依赖于该图像如此简单可解析。