Şeffaf bir PNG görüntüsünü PIL kullanarak başka bir görüntü ile birleştirmek


151

Şeffaf bir png resmim var "foo.png" ve başka bir resim açtım

im = Image.open("foo2.png");

Şimdi ihtiyacım olan şey foo.png'yi foo2.png ile birleştirmek.

(foo.png bazı metinler içerir ve bu metni foo2.png dosyasına yazdırmak istiyorum)


71

6
Bunu aklımda tutacağım, teşekkürler !!
Arackna

Yanıtlar:


288
import Image

background = Image.open("test1.png")
foreground = Image.open("test2.png")

background.paste(foreground, (0, 0), foreground)
background.show()

İlk parametre .paste()yapıştırılacak görüntüdür. İkincisi koordinatlar ve gizli sos üçüncü parametredir. Görüntüyü yapıştırmak için kullanılacak bir maskeyi gösterir . Saydamlığı olan bir görüntü iletirseniz, alfa kanalı maske olarak kullanılır.

Dokümanları kontrol edin .


6
Ön planın her durumda saydamlık içerdiğinden emin olmak foreground.convert('RGBA')için mask parametresini kullanın .
Mark Ransom

2
Teşekkürler. Üçüncü parametreyi çok özlüyordum.
Silouane Gerin

13
Ben alıyorumValueError: bad transparency mask
Deniz Özger

2
Gizli sos lezzetliydi
AFP_555

3
@DenizOzger ValueError: bad transparency maskKullanımı düzeltmek içinbg.paste(fg, (0, 0), fg.convert('RGBA'))
Mingwei Samuel

66

Image.pastearka plan resmi saydamlık içerdiğinde beklendiği gibi çalışmaz. Gerçek Alpha Compositing kullanmanız gerekir .

Pillow 2.0 alpha_compositebunu yapan bir işlev içerir .

background = Image.open("test1.png")
foreground = Image.open("test2.png")

Image.alpha_composite(background, foreground).save("test3.png")

EDIT: Her iki görüntünün RGBA türünde olması gerekir. Bu yüzden convert('RGBA')paletlendiyse çağırmanız gerekir , vb. Arka planda alfa kanalı yoksa, normal yapıştırma yöntemini kullanabilirsiniz (bu daha hızlı olmalıdır).


PIL ile yarı saydam bir görüntüyü diğerine yerleştirmek için paste () kullandım ve beklediğim gibi çalıştı. Beklediğiniz gibi hangi şekilde çalışmıyor?
Peter Hansen

3
@PeterHansen, paste () "arka plan resmi saydamlık içerdiğinde" beklendiği gibi çalışmaz.
homm


@homm teşekkürler. Çok uzun zaman önceydi denediklerimi hatırlamıyorum. Görünüşe göre arka plan resminden bahsettiğiniz kısmı da saydamım.
Peter Hansen

4
Ben olsun ValueError: image has wrong madehem de @DenizOzger
digitaldavenyc

48

Gibi OLT önce de işaret Image.pastedüzgün çalışmıyor, ne zaman, kaynak ve hedef hem alfa içerir.

Aşağıdaki senaryoyu düşünün:

Her ikisi de alfa içeren iki test görüntüsü:

resim açıklamasını buraya girin resim açıklamasını buraya girin

layer1 = Image.open("layer1.png")
layer2 = Image.open("layer2.png")

Aşağıdaki Image.pastegibi kullanarak görüntü birleştirme :

final1 = Image.new("RGBA", layer1.size)
final1.paste(layer1, (0,0), layer1)
final1.paste(layer2, (0,0), layer2)

aşağıdaki görüntüyü üretir (üst üste bindirilmiş kırmızı piksellerin alfa kısmı tamamen 2. katmandan alınır. Pikseller doğru şekilde karıştırılmamış):

resim açıklamasını buraya girin

Aşağıdaki Image.alpha_compositegibi kullanarak görüntü birleştirme :

final2 = Image.new("RGBA", layer1.size)
final2 = Image.alpha_composite(final2, layer1)
final2 = Image.alpha_composite(final2, layer2)

aşağıdaki (doğru) görüntüyü üretir:

resim açıklamasını buraya girin


1
Ekran görüntüleri için teşekkürler! Gerçekten yardımcı olur!
Viet

1
Ancak alpha_compositeofseti ayarlayamazsınız, pasteişlevi tamamen değiştirmek için bir örnek vermek ister misiniz ?
Mithril

3
Gargara görüntüsüyle aynı boyutta yeni bir boş görüntü oluşturmanız, katmanı uygun konuma yapıştırmanız ve yeni görüntüyü hedef görüntünün üzerine karıştırmak için alpha_compositing kullanmanız gerekir.
P.Melch

11

Karışım da kullanılabilir:

im1 = Image.open("im1.png")
im2 = Image.open("im2.png")
blended = Image.blend(im1, im2, alpha=0.5)
blended.save("blended.png")

1
Bu benim için ascetically çalıştı. Görüntüler tam olarak aynı boyutta olmalı, ancak sorun yok. Yapıştırma fonksiyonu benim için pek kesmedi ...
Liviu Sosu

2
'ValueError: görüntüler eşleşmiyor'
Schütze

2
Muhtemelen farklı boyutlardadırlar. Bunlardan birini ölçeklendirmeniz veya kırpmanız gerekebilir.
nvd

2
@ Schütze nvd adlı kullanıcının yorumuna bakın çünkü o ping yapmadı (@blahblah kullanarak)
MilkyWay90

1
def trans_paste(bg_img,fg_img,box=(0,0)):
    fg_img_trans = Image.new("RGBA",bg_img.size)
    fg_img_trans.paste(fg_img,box,mask=fg_img)
    new_img = Image.alpha_composite(bg_img,fg_img_trans)
    return new_img

2
Merhaba, Cevabınıza biraz daha bağlam ekleyebilir misiniz? Aksi takdirde, talep eden kişinin arkasındaki "neden" i öğrenmesi olası değildir.
jimf

0

Benzer bir soru vardı ve bir cevap bulmakta zorluk çekti. Aşağıdaki işlev, saydamlık parametresine sahip bir görüntüyü belirli bir ofsetteki başka bir görüntüye yapıştırmanıza olanak tanır.

import Image

def trans_paste(fg_img,bg_img,alpha=1.0,box=(0,0)):
    fg_img_trans = Image.new("RGBA",fg_img.size)
    fg_img_trans = Image.blend(fg_img_trans,fg_img,alpha)
    bg_img.paste(fg_img_trans,box,fg_img_trans)
    return bg_img

bg_img = Image.open("bg.png")
fg_img = Image.open("fg.png")
p = trans_paste(fg_img,bg_img,.7,(250,100))
p.show()

ValueError: images do not match
lllllllllllll

0

Kendim üzerinde çalıştığım bir projede @Melch kullanıcısı tarafından yapılan ve @ Mitril tarafından önerilen bu yorumun önerisini kendim kodladım.

Ben de sınır güvenliğini kodladım, işte kodu . (Belirli bir taahhüdü bağladım çünkü bu deponun geleceğinde işler değişebilir)

Not: np.array(Image.open(...))A ve B girişleri copy_fromve bu bağlantılı işlev overlayargümanları gibi resimlerden numpy diziler bekliyorum .

Bağımlılıklar, copy_fromdilimin hemen önündeki fonksiyon, yöntem ve dilimleme için PIL Resim içeriği olarak numpy dizileridir.

Dosya çok sınıfa yönelik olsa da, bu işlevi kullanmak istiyorsanız , arka plan resmi numpy dizinizi overlay_transparentyeniden adlandırdığınızdan emin olun self.frame.

Veya tüm dosyayı kopyalayabilir (muhtemelen bazı içe aktarmaları ve Utilssınıfı kaldırabilirsiniz ) ve bu Frame sınıfıyla şu şekilde etkileşim kurabilirsiniz:

# Assuming you named the file frame.py in the same directory
from frame import Frame

background = Frame()
overlay = Frame()

background.load_from_path("your path here")
overlay.load_from_path("your path here")

background.overlay_transparent(overlay.frame, x=300, y=200)

Daha sonra background.frameüst üste bindirilmiş ve alfa birleştirilmiş diziniz var, ondan bir PIL görüntüsü overlayed = Image.fromarray(background.frame)veya benzeri bir şey alabilirsiniz:

overlayed = Frame()
overlayed.load_from_array(background.frame)

Ya da background.save("save path")doğrudan alfa bileşimli dahili self.framedeğişkenden aldığı gibi.

Dosyayı okumak ve yöntemler gibi kodlu bu uygulama I başka güzel işlevlerini bulabilirsiniz get_rgb_frame_array, resize_by_ratio, resize_to_resolution, rotate, gaussian_blur, transparency, vignetting:)

Muhtemelen resolve_pendingyöntemi o projeye özgü olarak kaldırmak istersiniz .

Size yardımcı olduysam sevindim, bahsettiğim projenin repo'suna baktığınızdan emin olun , bu soru ve konu geliştirme konusunda bana çok yardımcı oldu :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.