2016-08-23 2 views
1

Я использовал этот следующий код от другого StackOverflow размещатьОстаточные белые пиксели на прозрачном фоне от PIL

from PIL import Image as image 

img = image.open('output.png') 
img = img.convert("RGBA") 
datas = img.getdata() 

newData = [] 
for item in datas: 
    if item[0] == 255 and item[1] == 255 and item[2] == 255: 
     newData.append((255, 255, 255, 0)) 
    else: 
     newData.append(item) 

img.putdata(newData) 
img.save("img2.png", "PNG") 

превратить фон моего Png к прозрачным. Однако, когда я попытался добавить некоторые фигуры в powerpoint под прозрачным изображением, у него все еще остались остаточные белые пиксели. Кто-нибудь знает, как это решить?

enter image description here

+1

Сколько вы хотите поставить меня, что те * не * на самом деле белые пиксели? – usr2564301

+0

Это на самом деле не связано с программированием, но с основными концепциями цифрового изображения (сглаживание, с одной стороны). Эти пиксели не являются белыми, открывают изображение в некоторых средствах просмотра/редактирования изображений, масштабируют и проверяют их. – leonbloy

ответ

2

Эти пиксели не точно "белый". Цвет, который вы тестируете и удаляете с изображения :, его значение #FFFFFF. Но эти наклонные линии сильно сглажены, «исчезают» от чистого белого фона до чистого цвета центра линий.

Это можно увидеть при масштабировании просто бит подростка:

antialiasing at work

Вы можете понизить порог, когда сделать пиксель полностью прозрачным:

if item[0] > 240 and item[1] > 240 and item[2] > 240: 
    newData.append((255, 255, 255, 0)) 
else: 
    newData.append(item) 

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

Но нет никакой причины использовать маску да/нет с изображениями PNG! PNG поддерживает полную 8-битную прозрачность, и поэтому вы можете сделать «сплошные» центральные линии полностью непрозрачными, сплошная белая полностью прозрачная и постепенно увеличивающиеся темные пиксели между этими значениями.

Это работает лучше всего, если вы знаете точный исходный цвет, который использовался для рисования линий. Измеряя его с помощью Adobe PhotoShop, я получаю что-то вроде #818695. Подключив эти значения в вашу программу и доведением блик "(в сторону белого) к прозрачности, сплющенный в направлении полного возможного диапазона, я предлагаю этот код:

from PIL import Image as image 

img = image.open('input.png') 
img = img.convert("RGBA") 
datas = img.getdata() 

retain = (0x81,0x86,0x95) 
retain_gray = (39*retain[0] + 50*retain[1] + 11*retain[2]) 

newData = [] 
for item in datas: 
    if item[0] > retain[0] and item[1] > retain[1] and item[2] > retain[2]: 
     # convert to grayscale 
     val = 39*item[0] + 50*item[1] + 11*item[2] 
     # invert 
     val = 25500 - val; 
     # difference with 'retain' 
     val = retain_gray - val 
     # scale down 
     val = 255*val/retain_gray 
     # invert to act as transparency 
     transp = 255-val 
     # apply transparency to original 'full' color value 
     newData.append((retain[0], retain[1], retain[2], transp)) 
    else: 
     newData.append(item) 

img.putdata(newData) 
img.save("output.png", "PNG") 
print "done" 

Что по существу делает это преобразование входного изображения в оттенках серого , масштабируя его (потому что масштаб от самого темного до легкого должен быть в полном диапазоне прозрачности 0..255), а затем использовать это как «прозрачный» байт. Результат намного лучше, чем ваш вкл/выкл подхода:

transparency added

+1

Это не идеальное решение, потому что цвета пикселей уже смешиваются в зависимости от их прозрачности. Вам нужно установить значения пикселей для 'сохранения [0], сохранить [1], сохранить [2], transp' вместо' item [0], item [1], item [2], transp'. –

+0

@MarkRansom: хорошо сбивай меня с мягкой пером. Это действительно заметное улучшение! (Замечание Марка заключается в том, что * добавление * прозрачности делает пиксели светлее, поэтому вам нужно «удалить» легкость от оригинала - уже светлее - пиксели. И это должно снова привести к (предположительно) оригинальному цвету.) – usr2564301

Смежные вопросы