Изменение цвета пикселей в png не работает правильно (питон, подушка) - PullRequest
0 голосов
/ 18 ноября 2018

Я пытаюсь написать скрипт на 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 голосов
/ 19 ноября 2018

Изображение содержит альфа-прозрачность , и большие блоки, которые вы видите, на самом деле выглядят таковыми в оригинале - но альфа-маска скрывает их. Фон, который вы видите белым в этом посте, на самом деле не белый, а полностью прозрачный. Другие программы просмотра изображений могут показывать даже серый или серый клетчатый фон.

Проблема почти сразу же появляется в вашем коде, потому что вы сглаживаете изображение в 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

, где все почти полностью прозрачные пиксели заменены фактическими белыми, а каждый небелой пиксель заменен чистым синим. Этот последний шаг, кстати, также убил сглаживание по краю, но это часть игры. Это можно сохранить, но это будет немного больше кода.


ª Вы можете назвать это ошибкой преобразования PIL. Все, что делает преобразование, это выбрасывает весь альфа-канал. С другой стороны, для правильного удаления альфа потребуется указать цвет фона. См. Как я могу установить фон прозрачного изображения на белый, используя PIL? для примера того, как это сделать, если вам потребуется.

0 голосов
/ 18 ноября 2018

Сохранение файла в формате BMP устранило проблему.

...