1. 程式人生 > >python gif轉字元畫的實現

python gif轉字元畫的實現

功能:該程式可將gif圖片匯入並轉換成字元組成的gif。
原理是現將匯入的gif圖片進行分割,逐張圖片獲取灰度並用字元代替,在所有圖片都處理完後重新生成gif圖片並匯出。
由兩個檔案組成,auth為主介面,fine為圖片處理程式。

最後一次測試的執行環境:python3.7 // pycharm2018.2.4

檔案“auth.py

import sys,fine,os
from PyQt5.QtWidgets import (QApplication, QPushButton, QMessageBox, QLabel, QLineEdit, QFileDialog,QWidget )
from PyQt5.QtGui import QCursor,QFont,QMovie,QPalette,QColor,QPixmap
from PyQt5.QtCore import Qt,QObject,QThread, pyqtSignal
class ui(QWidget):
    ##########      介面初始化   ################

    def __init__(self):
        super(ui, self).__init__(None,Qt.FramelessWindowHint)
        self.cinit()
        self.winit()
        self.fileName=0
        self.bu5.setEnabled(False)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.m_flag = True
            self.m_Position = event.globalPos() - self.pos()  # 獲取滑鼠相對視窗的位置
            event.accept()

    def mouseMoveEvent(self, e):
        if Qt.LeftButton and self.m_flag:
            self.move(e.globalPos() - self.m_Position)  # 更改視窗位置

    def mouseReleaseEvent(self, QMouseEvent):
        self.m_flag = False
        self.setCursor(QCursor(Qt.ArrowCursor))

    def mouseDoubleClickEvent(self, QMouseEvent):
        return None

    def winit(self):
        self.window2 = MyWindow2()  # 自定義視窗
        self.window2.before_close_signal.connect(self.echo)

    def cinit(self):
        lbl1 = QLabel('GIF圖片轉字元', self)
        lbl1.move(114, 20)
        lbl1.setFont(QFont("Microsoft YaHei", 13))

        lbl2 = QLabel('Made by SWW', self)
        lbl2.move(270, 230)

        lbl3 = QLabel('2018/12/4', self)
        lbl3.move(180, 230)

        self.lbl4 =QLabel("正在轉換中...",self)
        self.lbl4.move(124, 189)
        self.lbl4.hide()

        self.label = QLabel('', self)
        self.label.move(146, 140)
        self.movie = QMovie('pic/waiting2.gif')
        self.label.setMovie(self.movie)
        self.movie.start()
        self.label.hide()


        self.bu1 = QPushButton('選擇圖片', self)
        self.bu1.move(282, 86)
        self.bu1.resize(90, 30)
        self.bu1.clicked.connect(self.showDialog)


        self.bu2 = QPushButton('開始轉換', self)
        self.bu2.move(282, 132)
        self.bu2.resize(90, 30)
        self.bu2.clicked.connect(self.bu2_clicked)

        self.bu3 = QPushButton(self)
        self.bu3.move(373, 0)
        self.bu3.resize(14, 14)
        self.bu3.setWindowOpacity(0.9)
        # self.bu3.setIcon(QIcon("bu3.png"))
        self.bu3.setStyleSheet(
            "QPushButton{background-image: url(pic/bu3.png)}"
            "QPushButton{border:5px}"
            "QPushButton:hover{background-image: url(pic/bu3_1.png)}")
        self.bu3.clicked.connect(self.bu3_clicked)

        self.bu4 = QPushButton(self)
        self.bu4.move(350, 0)
        self.bu4.resize(14, 14)
        self.bu4.setWindowOpacity(0.9)
        # self.bu3.setIcon(QIcon("bu4.png"))
        self.bu4.setStyleSheet(
            "QPushButton{background-image: url(pic/bu4.png)}"
            "QPushButton{border:5px}"
            "QPushButton:hover{background-image: url(pic/bu4_1.png)}")
        self.bu4.clicked.connect(self.bu4_clicked)

        self.bu5 =  QPushButton("終止轉換",self)
        self.bu5.move(282, 182)
        self.bu5.resize(90, 30)
        self.bu5.clicked.connect(self.bu5_clicked)

        self.setGeometry(800, 300, 400, 250)
        self.setWindowOpacity(0.90)
        self.setWindowFlags(Qt.CustomizeWindowHint|
                            Qt.WindowStaysOnTopHint)
        self.tex = QLineEdit("", self)
        self.tex.move(76, 89)
        self.tex.resize(200, 25)
        palette1 = QPalette()
        palette1.setColor(self.backgroundRole(), QColor(255, 255, 255))
        self.setPalette(palette1)

    def bu5_clicked(self):
        fine.isgoingon = 0
        self.lbl4.setText("正在取消操作")
    def bu3_clicked(self):
        self.close()

    def bu4_clicked(self):
        self.showMinimized()

    def bu2_clicked(self):
        fine.isgoingon = 1

        if os.path.exists(self.tex.text()):
            self.tinit()
            self.bu5.setEnabled(True)
        else:
            self.window2.show()


    def showDialog(self):
        fileName1, filetype = QFileDialog.getOpenFileName(self,
                                                          "選取檔案",
                                                          "C:\\Users\\10698\PycharmProjects\\untitled1\\test",
                                                          "(*.gif)")  # 設定副檔名過濾,注意用雙分號間隔
        self.fileName=fileName1
        print(fileName1, filetype)
        self.tex.setText(fileName1)

    def action_shift(self):

        self.a = self.tex.text()
        fine.action(self.a)


    def thread_exit(self):
        self.thread.quit()
        self.label.hide()
        self.lbl4.hide()
        self.lbl4.setText("正在轉換中...")
        self.bu1.setEnabled(True)
        self.bu2.setEnabled(True)
        self.bu5.setEnabled(False)

    '''
    def closeEvent(self, event):
        try:
            customMsgBox = QMessageBox(self)

            yesButton = customMsgBox.addButton(self.tr("確定"), QMessageBox.ActionRole)
            noButton = customMsgBox.addButton(self.tr("取消"), QMessageBox.ActionRole)
            customMsgBox.setText(self.tr("你確定要退出嗎?"))
            customMsgBox.setWindowTitle(self.tr("通批警告"))
            customMsgBox.exec_()
            button = customMsgBox.clickedButton()
            if button == yesButton:
                event.accept()
            else:
                event.ignore()
        except Exception as e:
            print(e)
    '''
    def tinit(self):
        # 建立執行緒
        self.label.show()
        self.lbl4.show()
        self.bu1.setEnabled(False)
        self.bu2.setEnabled(False)
        self.backend = BackendThread()
        self.backend.update_date.connect(self.handleDisplay)
        self.thread = QThread()
        self.backend.moveToThread(self.thread)
        self.thread.started.connect(self.backend.run)
        self.backend.finished.connect(self.thread_exit)
        self.thread.start()


    def handleDisplay(self):
        print("sss")

    def echo(self, value):
        '''顯示對話方塊返回值'''
        QMessageBox.information(self, "返回值", "得到",
                                QMessageBox.Yes | QMessageBox.No)

class MyWindow2(QWidget):

    before_close_signal = pyqtSignal(int)
    def __init__(self):
        super().__init__()
        lbl6 = QLabel('', self)
        lbl6.move(0, 0)
        lbl6.resize(300, 250)

        pixmap=QPixmap("pic/loginfail.jpg")
        lbl6.setPixmap(pixmap)
        lbl6.move(0,18)
        lbl7 = QLabel('圖片路徑不對哦O(∩_∩)O', self)
        lbl7.setFont(QFont("Microsoft YaHei", 12))
        lbl7.move(15, 272)

        self.bu3 = QPushButton(self)
        self.bu3.move(228, 0)
        self.bu3.resize(14, 14)
        self.bu3.setWindowOpacity(0.9)
        # self.bu3.setIcon(QIcon("bu3.png"))
        self.bu3.setStyleSheet(
            "QPushButton{background-image: url(pic/bu3.png)}"
            "QPushButton{border:5px}"
            "QPushButton:hover{background-image: url(pic/bu3_1.png)}"
        )
        self.bu3.clicked.connect(self.bu3_clicked)
        self.setWindowTitle('無法開始')
        self.resize(250, 300)
        self.setWindowFlags(Qt.CustomizeWindowHint|
                            Qt.WindowStaysOnTopHint)
        palette1 = QPalette()
        palette1.setColor(self.backgroundRole(), QColor(255, 255, 255))
        self.setPalette(palette1)
    def bu3_clicked(self):
        self.close()
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.m_flag = True
            self.m_Position = event.globalPos() - self.pos()  # 獲取滑鼠相對視窗的位置
            event.accept()

    def mouseMoveEvent(self, e):
        if Qt.LeftButton and self.m_flag:
            self.move(e.globalPos() - self.m_Position)  # 更改視窗位置

    def mouseReleaseEvent(self, QMouseEvent):
        self.m_flag = False
        self.setCursor(QCursor(Qt.ArrowCursor))

    def mouseDoubleClickEvent(self, QMouseEvent):
        return None



class BackendThread(QObject):
    finished = pyqtSignal()
    update_date = pyqtSignal(str)
    stopped = pyqtSignal()
    def __init__(self):
        super().__init__()
        self.ex = ui
    # 處理業務邏輯
    def run(self):
        ex.action_shift()
        self.finished.emit()

if __name__ == '__main__':
    # 建立應用程式和物件

    app = QApplication(sys.argv)
    ex = ui()
    ex.show()
    sys.exit(app.exec_())





檔案“fine.py

from PIL import Image,ImageDraw
import os,imageio
CUR_PATH = r'imgs'
isgoingon = 1
def img_src(filename):
    gif_img = Image.open(filename)
    lx = gif_img.tell()
    gif_img.seek(lx)
    i=0

    try:
        while True:
            img_i = deal(gif_img)
            img_i.save("imgs/img"+str(i)+".png")
            gif_img.seek(gif_img.tell()+1)
            i += 1
    except EOFError:
        print("逐幀處理完成!")
        pass

def deal(girf_img):

    pix=[
         "Z", "O", "0", "Q", "L", "C", "J", "U", "Y", "X", "z", "c", "v", "u", "n", "x", "r", "j", "f",
         "t", "/", "\\","|","?"," - ","_"," + ","~"," < "," > ",
         ";",": ",", ","`","'","."," "]

    new_im = girf_img.convert("L")
    newL = Image.new("L",(new_im.width,new_im.height),255)
    draw = ImageDraw.Draw(newL)
    fillColor = "#ff0000"
    for x in range(0,new_im.width,4):
        for y in range(0, new_im.height, 4):
            xy_degree = new_im.getpixel((x,y))
            index = int(xy_degree/(256/len(pix)))
            draw.text((x,y),pix[index],fill=fillColor)
    return newL
def img_created():

    files = os.listdir("imgs")

    for i in range(len(files)):
        im = Image.open("imgs/img"+str(i)+".png")
        (x, y) = im.size  # read image size
        x_s = 800  # define standard width
        y_s = y * x_s / x  # calc height based on standard width
        out = im.resize((int(x_s), int(y_s)), Image.ANTIALIAS)  # resize image with high-quality
        out.save("imgs/img"+str(i)+".png")
    print(len(files))
    frames = []

    for i in range(len(files)):
        frames.append(imageio.imread("imgs/img"+str(i)+".png"))
    imageio.mimsave("final.gif",frames,'GIF',duration = 0.15)
    print("gif已生成")

def del_file(path):
    ls = os.listdir(path)
    for i in ls:
        c_path = os.path.join(path, i)
        os.remove(c_path)
def show():
    os.startfile("final.gif")

def action(filename):
    path =os.getcwd()
    if not os.path.exists(path+"\imgs"):
        os.mkdir("imgs")
    if ifgoing() == 0:
        return
    del_file("imgs")
    if ifgoing() == 0:
        return
    img_src(filename)
    if ifgoing() == 0:
        return
    img_created()
    if ifgoing() == 0:
        return
    show()

def ifgoing():
    if isgoingon == 1:
        return 1
    else :
        return 0