更改png中的像素颜色无法正常工作(Python,枕头)

时间:2018-11-18 17:42:16

标签: python image-processing python-imaging-library

我正在尝试编写python脚本来更改png文件中文本的颜色。这是原始图像original

的示例

例如,假设我要将品红色更改为蓝色。我的脚本将非黑色(255,255,255)的所有颜色更改为蓝色。我的假设是,这会将品红色文本更改为蓝色,因为图像中的所有其他内容都是不同的单一纯色(被python读取为黑色)。相反,这是我得到output

的结果

显然,这是不正确的。我有点难过。谁能告诉我发生了什么事以及如何解决这个问题?这是我第一次尝试使用python进行图像处理。

这是我的代码

from __future__ import division
from pylab import*
from math import*
from random import*
from scipy.optimize import curve_fit
import numpy as np

from PIL import Image 

# https://www.codementor.io/isaib.cicourel/image-manipulation-in-python-du1089j1u
#change color 
#https://stackoverflow.com/questions/36468530/changing-pixel-color-value-in-pil



image_name = 'Q_test.png'
test_image = 'Q_blue.png'
R1_Path = "C:/Users/PancakeMSTR/Desktop/Keyboard Related/Fusion Keycaps/Cherry/UpdatedLegends/Katakana_Updated/R1/"

image = Image.open(R1_Path+image_name)
image = image.convert('RGB') 
colors = image.getcolors()
pixelMap = image.load() 

newImg = Image.new(image.mode,image.size) 
pixelsNew = newImg.load() 
width,height = newImg.size
for i in range(width): 
    for j in range(height): 
        if pixelMap[i,j] != (255,255,255): 
            pixelsNew[i,j] = (0,0,255)
        else: 
            pixelsNew[i,j] = pixelMap[i,j]
image.close() 
newImg.save(R1_Path+test_image)

谢谢!让我知道是否需要进一步的信息。很高兴澄清我所说的话。

2 个答案:

答案 0 :(得分:0)

将其另存为BMP文件可解决此问题。

答案 1 :(得分:0)

图像包含 alpha透明度,并且您看到的大块实际上以原始形式显示,但是alpha蒙版将其隐藏。您在这篇文章中看到的白色背景实际上不是白色,而是完全透明的。其他图像查看器可能显示均匀的灰色或灰色的方格背景。

该问题几乎在您的代码中立即引入,因为您将图像展平为RGB:

image = Image.open(R1_Path+image_name)
image = image.convert('RGB') 

现在image.show()会告诉您,正是在这一点上,透明性被删除,并出现了大块。ª

不过,似乎没有理由转换为RGB,因为该图像已经是一个了。所以为什么不保留它原样。唯一的事情是,当您测试非白色像素时,您必须首先测试其基础颜色(白色)是否由于以下原因尚未真正可见:透明度。然后,仅在可见像素时,测试其颜色。

除了对“白色”进行精确测试(无论如何,您都需要重新考虑,因为此图像中没有纯白色)之外,我这里仅测试一个通道。对于其他图像,这可能不起作用,并且您需要一些启发式公式-例如,将颜色转换为灰度。由于这对您的图片有用,因此我们将不做进一步调查。

from PIL import Image 
image = Image.open('eq2hl.png')
pixelMap = image.load()
newImg = Image.new(image.mode,image.size)
pixelsNew = newImg.load() 
width,height = newImg.size
for i in range(width): 
    for j in range(height):
        pixelsNew[i,j] = pixelMap[i,j]
        if pixelMap[i,j][3] < 250:
            pixelsNew[i,j] = (255,255,255,255)
        elif pixelMap[i,j][0] < 255:
            pixelsNew[i,j] = (0,0,255,255)
newImg.show()

...以及结果:

transparent/pink image converted to white/blue

,几乎所有完全透明的像素都用 actual 白色替换,每个非白色像素都用纯蓝色替换。顺便说一句,最后一步也消除了边缘的抗锯齿,但这是游戏的一部分。可以保留它,但是要多一些代码。


ª您可以将其命名为PIL转换错误。转换所做的所有事情都是丢弃整个alpha通道。另一方面,正确删除 则需要您提供背景色。请参阅How can I set the background of a transparent image to white, using PIL?,以获取有关如何执行此操作的示例(如果需要)。