pyqt5で画像全体を透明化させようとすると背景に色がつく

投稿者: Anonymous

pyqt5で画像全体を徐々に透明化させたいです。下は試しに書いてみたコードです。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtGui,QtCore, QtWidgets
import os.path
from PIL import Image, ImageOps, ImageFilter
from PIL.ImageQt import ImageQt



class Example(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.button1 = QtWidgets.QPushButton('実行',self)
        self.button1.clicked.connect(self.calc)
        self.count=255

        self.button2 = QtWidgets.QPushButton(self)
        global img
        img = "./image/star.png"
        self.button2.setIcon(QIcon(img))
        self.button2.setIconSize(QSize(400,300))

        layout=QtWidgets.QVBoxLayout()
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)

        self.setLayout(layout)


    def calc(self):
        image = Image.open(img)
        image=image.copy()
        self.count=self.count-10
        if self.count<0:
            self.count=0
        else:
            pass
        image.putalpha(self.count)#0~255まで

        qim = ImageQt(image)
        qim2=QPixmap.fromImage(qim)
        self.button2.setIcon(QIcon(qim2))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_()

これを実行すると次のようなGUIが作成されます。
画像
星の画像はパワーポイントで保存した図形で、背景が透明になっています。ここで、実行ボタンを押すと、その度に星の画像が徐々に透明化されていくようにコードを書いたつもりです。しかし、実際に実行ボタンを押すと、次のように星の背景が黒い画像となりました。
画像2
何故こんなことが起こってしまうのでしょうか。

解決

画像の背景を透過させても元の色はそのまま情報として残っているみたいですね。そしてputalpha関数では画像全体を透過させる際、元の背景の色が復活してしまうようです。一応、下の画像のように予め背景の色をいらない色に編集しておけば、画像を透過させたのち、改めてその色を完全に透過させることで実行は可能のようです。ここでは背景色を青色にしています。
画像
次は実際のコードです。

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5 import QtGui,QtCore, QtWidgets
import os.path
from PIL import Image, ImageOps, ImageFilter
from PIL.ImageQt import ImageQt
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import os




class Example(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.button1 = QtWidgets.QPushButton('実行',self)
        self.button1.clicked.connect(self.calc)
        self.count=255

        self.button2 = QtWidgets.QPushButton(self)
        self.image=Image.open("./image/star.png")
        self.image = self.image.convert("RGBA")
        self.button2.setIconSize(QSize(400,300))
        self.tranparent_blue(self.image)


        layout=QtWidgets.QVBoxLayout()
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)

        self.setLayout(layout)


    def calc(self):
        self.count=self.count-10
        if self.count<0:
            self.count=0
        else:
            pass
        self.image.putalpha(self.count)#0~255まで
        self.tranparent_blue(self.image)


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

        image.putdata(newData)
        qim = ImageQt(image)
        #image=QPixmap(image)
        qim2=QPixmap.fromImage(qim)
        self.button2.setIcon(QIcon(qim2))        

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    ex.show()
    app.exec_()

これを実行すると次のようなGUIが作成され、確かに背景を透明にしたまま、全体を半透明に出来ました。
画像2
今回は元画像が黒と白だけの単純な画像のため、青色を透過しても問題ありませんでしたが、より複雑でカラフルな画像で同じことをすると、画像内に透明部分が出来てしまうかもしれません。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *