H我的名字暗示我是代码新手,正在使用Python,非常感谢使用Python Imaging Library完成任务的一些帮助。
我有2个位图图像。第一张图片是彩色绘画,第二张图片只包含黑白像素...... 我想开发一个函数,接受两个图像作为参数来创建一个新的图像,基本上是第一个图像(绘画),第二个图像中的仅黑色像素,覆盖在上面它。第二个图像小于第一个图像,覆盖的像素需要位于新图像的中心。
我已经安装了PIL,并且能够使用以下代码使用以下代码成功显示第一个图像:
import PIL
from PIL import Image
painting = Image.open("painting.bmp")
painting.show()
我已经排除了使用.blend和.composite函数或ImageChops模块中的.multiply函数,因为图像的大小不同。
我相信我需要使用.getpixel / .putpixel或.getdata / .putdata来查找由元组(0,0,0)标识的黑色像素。 我正在考虑的PIL的裁剪和粘贴功能应该有助于从绘画中找出“区域”以用黑色像素覆盖,并且可以帮助将黑色像素置于绘画的中心?
所以我正在看这样的事情......
def overwrite_black(image1, image2):
image_1 = Image.open('painting.bmp')
image_2 = Image.open('black_white.bmp')
pixels = list(image_2.getdata())
for y in xrange(image_2.size[1]):
for x in xrange(image_2.size[0]):
if pixels ==(o,o,o):
image_2.putdata(pixels((x,y),(0,0,0)))
image_2.save('painted.bmp')
再一次,我是新人,所以对我很轻松,任何帮助都将非常感激。
干杯。
答案 0 :(得分:3)
所以我假设你只想将两张图像相互叠加,那就是它们的尺寸不同?如果我误解了,请原谅我,但是这里有一些代码可以将一个图像的黑色像素放到另一个图像上,即使黑白图像比另一个图像小。
Sourse Images(painting.bmp
和mask.bmp
)
输出:
“...新图像基本上是第一张图片(绘画),第二张图片中只有黑色像素,覆盖在它上面。” - 这就是你想要的吗?
基本上,代码只是将较小的图像与第一个图像一样大,方法是将其放在与第一个图像大小相同的空白图像的中心。
import PIL
from PIL import Image
from PIL import ImageChops # used for multiplying images
# open images
painting = Image.open("painting.bmp")
mask = Image.open("mask.bmp")
def black_onto(img1, img2):
# create blank white canvas to put img2 onto
resized = Image.new("RGB", img1.size, "white")
# define where to paste mask onto canvas
img1_w, img1_h = img1.size
img2_w, img2_h = img2.size
box = (img1_w/2-img2_w/2, img1_h/2-img2_h/2, img1_w/2-img2_w/2+img2_w, img1_h/2-img2_h/2+img2_h)
# multiply new mask onto image
resized.paste(img2, box)
return ImageChops.multiply(img1, resized)
out = black_onto(painting, mask)
out.show() # this gives the output image shown above
解释: (img1_w/2-img2_w/2, img1_h/2-img2_h/2, img1_w/2-img2_w/2+img2_w, img1_h/2-img2_h/2+img2_h)
好的,所以这很丑陋,但它真的很简单:box
定义画布上我们想要将蒙版放在哪个区域,即中心。 box
是一个4值元组,用于定义区域的左上角和右下角角的x和y,如下所示:{{ 1}}。不是x,y和宽度,高度,这将更方便。无论如何,要定义区域以使图像居中,那么代码就是我们得到的。
它是这样的:左上角角的x值等于大图像宽度的一半减去宽度的一半掩码图像。(我发现笔和纸在这里很有帮助。)左上角的y值也是如此。这是前两个值。
现在,如果元组接受(x1, y1, x2, y2)
,则后两个值将只是蒙版图像的尺寸。但他们不是,他们更多的是x和y职位。所以我们必须手动计算它们,通过使用相同的代码作为前两个值(左上角位置)和添加图像的宽度和高度,我们从一些变量({{ 1}}和(x, y, width, height)
)。因此,元组的后两个值与第一个和第二个相同,但添加了掩码(img2_w
)的 width 或 height 。
嗯,我希望这对你的项目有充分的理解和好运!
答案 1 :(得分:1)
好的,这是一个更通用和可扩展的替代解决方案。它有两个部分;首先,将较小的图像调整大小(但不缩放)到较大的图像的尺寸,然后将图像转换为仅由黑色或透明像素组成的图像,可以简单地粘贴到较大的图像上,然后,我们将你想要的东西留给我们。
<强>调整大小:强>
1: 2: 3:
可以使用此center_resize()
函数完成:
def center_resize(smaller, (width, height)):
resized = Image.new("RGB", (width, height), "white")
smaller_w, smaller_h = smaller.size
box = (width/2-smaller_w/2,
height/2-smaller_h/2,
width/2-smaller_w/2+smaller_w,
height/2-smaller_h/2+smaller_h)
resized.paste(smaller, box)
return resized
<强>过滤强>
此函数用于迭代图像中的所有像素,并将它们设置为指定的颜色(如果它们是指定的颜色)。 (否则它们会被设置为第三种指定颜色。)在这种情况下,我们希望将所有黑色像素保持为黑色,但将所有其他像素设置为完全透明的黑色。要做到这一点,你可以输入:
pixel_filter(image, condition=(0, 0, 0), true_colour=(0, 0, 0, 255), false_colour=(0, 0, 0, 0))
...它会返回一个过滤后的图像。
def pixel_filter(image, condition, true_colour, false_colour):
filtered = Image.new("RGBA", image.size)
pixels = list(image.getdata())
for index, colour in enumerate(pixels):
if colour == condition:
filtered.putpixel((index%image.size[1],index/image.size[1]), true_colour)
else:
filtered.putpixel((index%image.size[1],index/image.size[1]), false_colour)
return filtered
现在,在您的情况下,我们可以将这些应用于B&amp; W图像,只需将其粘贴到主图像上即可。
mask = center_resize(mask, painting.size)
mask = pixel_filter(mask, (0, 0, 0), (0, 0, 0, 255), (0, 0, 0, 0))
painting.paste(mask, (0, 0), mask)
painting.show()
输出:
查看此代码是否有用 - 将其拉开并使用您想要的内容!