2012-08-29 74 views
2

我必須用python使用PIL裁剪照片。
如果照片區域不夠,則該區域的其餘部分會塗成黑色。
如何使該區域變白?裁剪圖像,改變黑色區域,如果沒有足夠的照片區域在白色

這是現在使用的代碼我真的的一部分:

i = Image.open(filepath) 
box2 = (newX,newY,newX+newW,newY+newH) 
i2=i.crop(box=box2) 
i2.load() 
... 
i2.save(new_filepath) 
... 
white=(255,255,255) 
i3 = Image.new('RGB' , i2.size , white) 
i3.paste(i2) 
i3.save(filepath2,'PNG') 

作物正常工作,但我想白色而不是黑色在該地區的其餘部分。 我試圖創建一個帶有白色背景的新圖片並粘貼了圖片,但它沒有工作。

編輯: 例如輸出

example output

EDIT2:我原始圖像和用於croping
我更新了代碼
Remeber該作物COORDS可以是負的COORDS。

輸入&輸出例如
輸入IMG:http://i.imgur.com/vbmPy.jpg

box2=(-743, 803, 1646, 4307) 

輸出IMG:http://i.imgur.com/K7sil.jpg

回答

1

如果你可以使用numpy的,你可以這樣做:

i22 = flipud(asarray(i2).copy()) 
# calculate the area that its black, using the original size and the box information 
for i in xrange(blackrows): 
    i22[i:] = asarray([255,255,255]) 
# and and something like that to the blackcolumns 

我不不會使用PIL,但它可能具有一些像素處理功能。

+0

如果圖像已經是純黑色的是什麼?這在這種情況下不起作用 – Revelation

0

要完全按照您的要求進行操作,請將圖像轉換爲numpy數組,然後過濾全黑行和列(在第二個圖像上)。您不能簡單地將所有黑色像素設爲白色,因爲這會影響圖像內部的那些像素。

import numpy 
from PIL import Image 
img = Image.open("hHncu.png") # Imgur's naming scheme 
pix = numpy.array(img)  # Convert to array 

black = numpy.array([0,0,0,255]) 
white = numpy.array([255,255,255,255]) 

pix2 = pix.copy() 
dim = pix.shape 

for n in xrange(dim[0]): 
    if (pix[n,:]==black).all(): 
     pix2[n,:,numpy.newaxis] = white 

for n in xrange(dim[1]): 
    if (pix[:,n]==black).all(): 
     pix2[:,n,numpy.newaxis] = white 

# View the results 
from pylab import * 
subplot(121); imshow(pix) 
subplot(122); imshow(pix2) 
show() 

enter image description here

它看起來像有黑色和圖像之間的一些平滑,將需要更先進的過濾器來解決這個問題 - 但你可以看到如何從這裏開始!

+0

如果我在黑色區域畫白色矩形會怎麼樣?數組操作聽起來有點過度。這是一個網絡應用程序,因此加快它的一個重要因素。 – Revelation

+0

你當然可以這樣做,但是numpy是數組操作的_designed_,它們閃電般快,所以我不認爲這是一個問題。 – Hooked

+0

如果圖像已經是純黑色,該怎麼辦?這在這種情況下不起作用。 – Revelation

1

它在我看來像你做錯了什麼,你應該分享你的整個代碼和圖像。

我已經在PIL中做過這麼多次了,最簡單的解決方案一直是將作物粘貼到全白圖像上。

import Image 

# open source 
i = Image.open('hHncu.png') 

# crop it 
(newX , newY) = (110 , 0) 
(newW , newH) = (110 , 150) 
box_crop = (newX,newY,newX+newW,newY+newH) 
i2 = i.crop(box=box_crop) 
i2.load() 

# save it , just for testing 
i2.save('hHncu-out.png') 

# create the new image, and paste it in 
# note that we're making it 300x300 and have the background set to white (255x3) 
i3 = Image.new('RGB' , (300,300) , (255,255,255)) 
# paste it at an offset. if you put no offset or a box, i3 must match i2s dimensions 
i3.paste(i2 , (25,25)) 
# save it 
i3.save('hHncu-out-2.png') 
+0

我先試過這個解決方案。我用這個解決方案更新了代碼,但沒有運氣。我認爲這是因爲在裁剪之後,圖像已經有了黑色區域,並且我們將其複製/粘貼到新圖像上,並將其複製到黑色區域。我輸入和輸出文件。 – Revelation

+0

上述代碼按原樣運行。你可能在你的代碼中做錯了。 發佈導致錯誤的代碼的工作示例,以便人們可以更正您的錯誤。 –

+0

當裁剪區域超出照片區域時,上述代碼不起作用。用這個座標測試你的代碼:#裁剪它 '(newX,newY)=(-100,-100) (newW,newH)=(400,250)'你會看到結果 – Revelation

0

好的。所以這裏是我提到的想法的快速刺入。

的REBOX()函數返回一個「固定」的邊界框,以及一些偏移數據

這部作品在大多數情況下。我沒有整合偏移量數據,但它的一些版本可能會在i3.paste部分。

測試圖像,grid.png爲300x300,藍色線條爲50px,紅色線條爲150px,綠色線條爲200px。

你應該能夠根據你的確切需求調整它。

enter image description here

import Image 
i1 = Image.open('grid.png') 


DEBUG = True 

def rebox(box_original , box_crop_desired): 

    box_crop_new= list(box_crop_desired) 
    box_crop_offset = [ 0 , 0 ] 

    if box_crop_desired[0] < 0: 
     box_crop_new[0] = 0 
     box_crop_offset[0] = box_crop_desired[0] 

    if box_crop_desired[1] < 0: 
     box_crop_new[1] = 0 
     box_crop_offset[1] = box_crop_desired[1] 

    if box_crop_desired[2] > box_original[2]: 
     box_crop_new[2] = box_original[2] 

    if box_crop_desired[3] > box_original[3]: 
     box_crop_new[3] = box_original[3] 

    box_crop_offset = tuple(box_crop_offset) 
    box_crop_new = tuple(box_crop_new) 

    if DEBUG : 
     print "box_original      %s" % str(box_original) 
     print "box_crop_offset     %s" % str(box_crop_offset) 
     print "box_crop_desired     %s" % str(box_crop_desired) 
     print "box_crop_new      %s" % str(box_crop_new) 

    return (box_crop_new , box_crop_offset) 


(newX , newY) = (200 , 200) 
(newW , newH) = (400 , 400) 
box_crop_desired = (newX , newY , newX+newW, newY+newH) 
(box_crop , box_crop_offset) = rebox(i1.getbbox() , box_crop_desired) 

i2 = i1.crop(box=box_crop) 
i2.save('grid-out-b.png') 

i3 = Image.new('RGBA' , (newW , newH) , (255,255,255)) 
i3.paste(i2 , (0,0)) 
i3.save('grid-out-final-b.png')