[英]PIL putpixel does nothing
在高中時,我們開始使用Python,並要求我們使用Pillow
模塊對小型圖像處理器進行編程。 目標是打開一個文件,然后選擇一個過濾器。
我嘗試編程的第一個濾鏡是更改色溫。 但是tkinter還有一個極簡主義的界面,其中顯示了一些按鈕,並且可以正常工作。
這是打開文件的功能
def Ouvrir():
fichier = askopenfilename(title="Ouvrir une image",filetypes=[('jpg files','.jpg'),('all files','.*')])
global img
img =Image.open(fichier)
l, h = img.size
img.show() #visualisation de l'image
global img2
img2 = img #img2 est une copie de img
它創建一個從文件加載的全局img
圖像對象。 然后,將圖像的寬度和高度加載到l
和h
中。
為輸出圖像創建了另一個全局對象圖像img2
,它是img
的副本。
然后是處理圖像的功能
def filtreTC(): #Filtre permettant de changer la température de couleur
coef = sliderTC.get() / 100 #On récupère le coefficient à partir de l'échelle. Le coefficient compris entre -1 et 1: -1 = froid (image bleu-vert), 0 = neutre, 1 = chaud (image orangée)
fenTC.destroy() #On ferme la fenêtre
if(coef <= 0): #Calcul des coefficients rouges, verte et bleus
coefR = 1 + coef
coefV = 1 + (coef / 2)
coefB = 1
else:
coefR = 1
coefV = 1 - (coef / 2)
coefB = 1 - coef
for y in range(0, h, 1):
for x in range(0, l, 1):
r, v, b = img.getpixel((x, y))
r = int(float(r * coefR))
v = int(float(v * coefV))
b = int(float(b * coefB))
img2.putpixel((x, y), (r, v, b))
img2.show()
這是一個循環,掃描整個圖像並從img
獲取一個像素,將其rgb值乘以其相應的系數,然后將該像素放入img2
問題是它不起作用。 它沒有給出任何錯誤,但是當它顯示img2
時,它與img1
相同,就像putpixel
函數沒有執行任何操作一樣。
我檢查了很多東西,所以我知道問題既不是rgb值也不是x / y坐標。
img2 = img
img2 = Image.new("RGB", (l, h))
替換img2 = img
,得到的是黑色圖像。 img2.putpixel((x, y), (r, v, b))
img2.putpixel((100, 100), (127, 127, 127))
以使我應該得到一個灰色像素在左上角附近。 但是我仍然有黑色圖像。 然后,我嘗試刪除
global img2
img2 = img
從打開文件並放入的功能
img2 = Image.new("RGB", (l, h))
在fenTC.destroy()
,我得到了:
Exception in Tkinter callback
Traceback (most recent call last):
File "e:\xxxx\programmes\anaconda\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "H:\ISN\Programmes\TP-image\projet.py", line 62, in filtreTC
img2.show()
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\Image.py", line 2016, in show
_show(self, title=title, command=command)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\Image.py", line 2876, in _show
_showxv(image, **options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\Image.py", line 2881, in _showxv
ImageShow.show(image, title, **options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\ImageShow.py", line 51, in show
if viewer.show(image, title=title, **options):
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\ImageShow.py", line 75, in show
return self.show_image(image, **options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\ImageShow.py", line 95, in show_image
return self.show_file(self.save_image(image), **options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\ImageShow.py", line 91, in save_image
return image._dump(format=self.get_format(image), **self.options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\Image.py", line 639, in _dump
self.save(filename, format, **options)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\Image.py", line 1969, in save
save_handler(self, fp, filename)
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\BmpImagePlugin.py", line 319, in _save
(rawmode, stride, -1))])
File "e:\xxxx\programmes\anaconda\lib\site-packages\PIL\ImageFile.py", line 512, in _save
e.setimage(im.im, b)
SystemError: tile cannot extend outside image
基本上很多東西我都不知道它是什么意思,除了:
SystemError: tile cannot extend outside image
我檢查了x和y坐標,它們從未越過邊界,所以我不明白這是什么錯誤。
我花了幾個小時嘗試找出問題所在,並嘗試了許多不同的方法,但沒有一個起作用。 所以我認為最好尋求幫助
您的問題是您沒有創建副本 。 img2 = img
創建對同一對象的另一個引用,而不是新的單獨圖像。
要創建實際的副本,請使用image.copy()
方法 :
img2 = img.copy()
接下來,我會不使用循環和getpixel()
/ putpixel()
的組合。 您正在為出現多次的RGB值做雙重工作。 如果使用image.point()
方法,則可以對圖像每個波段中的每個唯一值使用公式,並將循環遍歷所有像素到庫中(快得多)。 它還可以為您復制圖像!
您需要創建一個表; 對於R,G和B值從0到255的值,計算可能的結果,並將這3 * 256個結果放入長列表中:
coefG = [i * (1 - (coef / 2)) for i in range(256)]
if coef <= 0:
coefR = [i * (1 + coef) for i in range(256)]
coefB = list(range(256))
else:
coefR = list(range(256))
coefB = [i * (1 - coef) for i in range(256)]
img2 = img1.point(coefR + coefG + coefB)
結果表用於圖像中的每個唯一顏色值。
您還可以將RGB圖像分成單獨的波段,將不同的系數公式作為函數應用到每個單獨的波段,然后將波段重新組合為新圖像:
r, g, b = img.split()
g = g.point(lambda i: i * (1 - (coef / 2)))
if coef <= 0:
r = r.point(lambda i: i * (1 + coef))
else:
b = b.point(lambda i: i * (1 - coef))
img = Image.merge('RGB', (r, g, b))
創建圖像過濾器時,您確實希望將輸入圖像作為函數參數傳遞,而不是使用全局變量。 還要傳遞系數:
def filtreTC(source_image, coef):
coefG = [i * (1 - (coef / 2)) for i in range(256)]
if coef <= 0:
coefR = [i * (1 + coef) for i in range(256)]
coefB = list(range(256))
else:
coefR = list(range(256))
coefB = [i * (1 - coef) for i in range(256)]
return source_image.point(coefR + coefG + coefB)
然后,可以根據需要將調用結果存儲在全局變量中,但是該函數現在可以獨立存在,並且可以在具有RGB PIL圖像對象的任何地方重復使用。 您可以使用滑塊值調用該函數:
coef = sliderTC.get() / 100
fenTC.destroy()
img2 = filtreTC(img, coef)
在個人資料圖片上使用以上內容
系數為0.75,我們得到:
-0.75導致:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.