我正在尝试使用Pillow(Python-imaging-library)库来创建一个轮廓/描边/边框(以任何颜色和宽度选择)在我的.png图像周围。您可以在这里看到原始图像和我想要的结果(由手机应用程序创建):https://istack.dev59.com/4x4qh.webp
您可以在此处下载原始图像的png文件:https://pixabay.com/illustrations/brain-character-organ-smart-eyes-1773885/
我已经在中等大小(1280x1138)上完成了它,但也许最好使用最小的大小(640x569)。
我尝试用两种方法解决这个问题。
第一种方法
第一种方法是创建一个完全黑色的brain.png图像,放大它,并将原始彩色的brain图像粘贴在其上。这是我的代码:
brain_black = Image.open("brain.png") #load brain image
width = brain_black.width #in order not to type a lot
height = brain_black.height #in order not to type a lot
rectangle = Image.new("RGBA", (width, height), "black") #creating a black rectangle in the size of the brain image
brain_black.paste(rectangle, mask=brain_black) #pasting on the brain image the black rectangle, and masking it with the brain picture
#now brain_black is the brain.png image, but all its pixels are black. Let's continue:
brain_black = brain_black.resize((width+180, height+180)) #resizing the brain_black by some factor
brain_regular = Image.open("brain.png") #load the brain image in order to paste later on
brain_black.paste(brain_regular,(90,90), mask=brain_regular) #paste the regular (colored) brain on top of the enlarged black brain (in x=90, y=90, the middle of the black brain)
brain_black.save("brain_method_resize.png") #saving the image
这种方法行不通,正如您在上面的图像链接中所看到的那样。它可能适用于简单的几何形状,但对于这样复杂的形状则行不通。
第二种方法
第二种方法是将大脑图像像素数据加载到二维数组中,并循环遍历所有像素。检查每个像素的颜色,在每个非透明像素(也就是 rgbA 表示中 A(或 Alpha)不为 0 的像素)中,在上方、下方、右侧、左侧、主对角线向下、主对角线向上、次对角线(/)向下和次对角线(/)向上绘制黑色像素。然后在第二个像素上方、第二个像素下方等处绘制像素。这是使用一个“for循环”完成的,重复次数是所需的笔画宽度(在本例中为30)。这是我的代码:
brain=Image.open("brain.png") #load brain image
background=Image.new("RGBA", (brain.size[0]+400, brain.size[1]+400), (0, 0, 0, 0)) #crate a background transparent image to create the stroke in it
background.paste(brain, (200,200), brain) #paste the brain image in the middle of the background
pixelsBrain = brain.load() #load the pixels array of brain
pixelsBack=background.load() #load the pixels array of background
for i in range(brain.size[0]):
for j in range(brain.size[1]):
r, c = i+200, j+200 #height and width offset
if(pixelsBrain[i,j][3]!=0): #checking if the opacity is not 0, if the alpha is not 0.
for k in range(30): #the loop
pixelsBack[r, c + k] = (0, 0, 0, 255)
pixelsBack[r, c - k] = (0, 0, 0, 255)
pixelsBack[r + k, c] = (0, 0, 0, 255)
pixelsBack[r - k, c] = (0, 0, 0, 255)
pixelsBack[r + k, c + k] = (0, 0, 0, 255)
pixelsBack[r - k, c - k] = (0, 0, 0, 255)
pixelsBack[r + k, c - k] =(0, 0, 0, 255)
pixelsBack[r - k, c + k] = (0, 0, 0, 255)
background.paste(brain, (200,200), brain) #pasting the colored brain onto the background, because the loop "destroyed" the picture.
background.save("brain_method_loop.png")
这种方法虽然可行,但非常耗时(每张图片和30像素笔划大约需要30秒)。我想要对多张图片进行此操作,所以这种方法并不适合我。
是否有更简单、更好的方法可以使用Python Pillow库来达到我的目的?我该怎么做? 另外,如何加快循环代码的执行速度(我了解Numpy和OpenCV,哪个更适合这个目的?)
我知道如果手机应用程序可以在几毫秒内完成此操作,那么Python也可以,但我没有找到任何方法。
谢谢。