PIL을 사용하여 투명 PNG 이미지를 다른 이미지와 병합하는 방법


151

투명한 png 이미지 "foo.png"가 있고 다른 이미지를 열었습니다.

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

이제 내가 필요한 것은 foo.png를 foo2.png와 병합하는 것입니다.

(foo.png에는 일부 텍스트가 포함되어 있으며 foo2.png에 해당 텍스트를 인쇄하고 싶습니다)


71
;파이썬에서 명령의 끝에서 사용하지 마십시오 : 그것은 못생긴 ...
nosklo

6
나는 내 마음에 그것을 유지합니다, 감사합니다 !!
Arackna

답변:


288
import Image

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

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

첫 번째 매개 변수 .paste()는 붙여 넣을 이미지입니다. 두 번째는 좌표이고 비밀 소스는 세 번째 매개 변수입니다. 이미지 붙여 넣기에 사용될 마스크 를 나타냅니다 . 투명도가있는 이미지를 전달하면 알파 채널이 마스크로 사용됩니다.

문서를 확인하십시오 .


6
모든 경우 전경에 투명도가 포함되도록하려면 foreground.convert('RGBA')마스크 매개 변수에 사용하십시오.
Mark Ransom

2
감사. 세 번째 매개 변수가 너무 누락되었습니다.
Silouane Gerin

13
나는오고있다ValueError: bad transparency mask
Deniz Ozger

2
비밀 소스는 맛있었습니다
AFP_555

3
@DenizOzger ValueError: bad transparency mask사용 을 수정 하기 위해bg.paste(fg, (0, 0), fg.convert('RGBA'))
Mingwei Samuel

66

Image.paste배경 이미지에 투명도가 포함되어 있으면 예상대로 작동하지 않습니다. 실제 알파 합성 을 사용해야 합니다.

Pillow 2.0에는이를 alpha_composite수행 하는 기능이 포함되어 있습니다 .

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

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

편집 : 두 이미지 모두 RGBA 유형이어야합니다. 따라서 convert('RGBA')팔레트 등이 있으면 호출해야합니다 . 배경에 알파 채널이없는 경우 일반 붙여 넣기 방법을 사용할 수 있습니다 (더 빠름).


방금 paste ()을 사용하여 PIL을 사용하여 반투명 한 이미지를 다른 이미지 위에 오버레이하고 예상대로 작동했습니다. 예상대로 작동하지 않습니까?
피터 한센

3
@PeterHansen, paste ()가 "배경 이미지에도 투명도가 포함되어있을 때"예상대로 작동하지 않습니다.
homm

1
@PeterHansen 예가 있습니다 : github.com/python-pillow/Pillow/issues/…
homm

@homm 감사합니다. 너무 오래 전에 내가 시도한 것에 대한 기억이 없습니다. 배경 이미지에 대해서도 인용 한 부분이 투명하지 않은 것 같습니다.
피터 한센

4
나는 ValueError: image has wrong made또한 @DenizOzger를 얻는다
digitaldavenyc

48

으로 OLT 이미 지적 Image.paste제대로 작동하지 않는 경우 소스 대상 모두 알파가 포함되어 있습니다.

다음 시나리오를 고려하십시오.

두 개의 테스트 이미지는 모두 알파를 포함합니다.

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

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

다음을 사용하여 이미지 합성 Image.paste:

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

다음 이미지를 생성합니다 (오버레이 된 빨간색 픽셀의 알파 부분은 2 번째 레이어에서 완전히 가져옵니다. 픽셀이 올바르게 혼합되지 않음).

여기에 이미지 설명을 입력하십시오

다음을 사용하여 이미지 합성 Image.alpha_composite:

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

다음과 같은 (정확한) 이미지를 생성합니다 :

여기에 이미지 설명을 입력하십시오


1
스크린 샷 감사합니다! 정말 도움이됩니다!
Viet 17

1
그러나 alpha_composite오프셋을 설정할 수 없습니다. paste기능 을 완전히 대체하는 예를 들어 주 시겠습니까?
Mithril

3
가제트 이미지와 동일한 크기의 빈 이미지를 새로 만들고 레이어를 올바른 위치에 붙여 넣은 다음 alpha_compositing을 사용하여 새 이미지를 대상 이미지와 혼합해야합니다.
P.Melch

11

블렌딩을 사용할 수도 있습니다.

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

1
이것은 나를 위해 열심히 일했습니다. 이미지의 크기는 정확히 같아야하지만 괜찮습니다. 붙여 넣기 기능은 나를 위해 그것을 잘 잘라하지 않았다 ...
Liviu Sosu

2
'ValueError : 이미지가 일치하지 않습니다'
Schütze

2
아마도 치수가 다른 것일 수 있습니다. 그중 하나를 스케일하거나 잘라야 할 수도 있습니다.
nvd

2
@ Schütze는 (@blahblah를 사용하여) 당신을 핑하지 않았기 때문에 nvd의 의견을 참조하십시오
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
안녕하십니까, 답변에 컨텍스트를 조금 더 추가 할 수 있습니까? 그렇지 않으면 요청자는 그 뒤에 "이유"를 배우지 않을 것입니다.
jimf

0

비슷한 질문이 있었고 답을 찾는 데 어려움이있었습니다. 다음 기능을 사용하면 특정 오프셋에서 다른 이미지 위에 투명도 매개 변수가있는 이미지를 붙여 넣을 수 있습니다.

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

필자는 @ P.Melch 사용자가 작성한 의견 과 내가 작업중 인 프로젝트에서 @Mithril 제안한 의견을 스스로 코딩 했습니다.

나는 범위 안전을 벗어났습니다. 여기에 대한 코드가 있습니다 . (이 저장소의 미래에 상황이 바뀔 수 있기 때문에 특정 커밋을 연결했습니다)

참고 : np.array(Image.open(...))입력 A와 B copy_from와이 연결된 함수 overlay인수 와 같이 이미지에서 numpy 배열을 기대 합니다.

종속성은 copy_from슬라이싱을위한 PIL 이미지 컨텐츠로서의 직전의 함수, 메소드 및 numpy 배열입니다.

파일은 클래스 지향적이지만 해당 함수를 사용 overlay_transparent하려면의 이름 self.frame을 배경 이미지 numpy 배열 로 바꾸십시오 .

또는 전체 파일을 복사하고 (일부 가져 오기 및 Utils클래스를 제거 할 수 있음 )이 Frame 클래스와 상호 작용할 수 있습니다.

# 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)

그런 다음 background.frame오버레이 및 알파 합성 배열로 PIL 이미지를 얻을 수 있습니다 overlayed = Image.fromarray(background.frame).

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

또는 background.save("save path")알파 합성 내부 self.frame변수 에서 직접 가져 오는 것처럼 .

당신은 파일을 읽고 방법처럼 코딩이 구현 I와 다른 좋은 기능을 찾을 수 있습니다 get_rgb_frame_array, resize_by_ratio, resize_to_resolution, rotate, gaussian_blur, transparency, vignetting:)

resolve_pending해당 프로젝트에 고유 한 메소드 를 제거하고 싶을 것입니다 .

내가 당신을 도우면 기쁘다. 내가 이야기 하고있는 프로젝트 의 저장소를 확인하십시오 .이 질문과 스레드는 개발에 많은 도움이되었습니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.