Python - 批量製做圖種

  什麼是圖種,就是一種包含壓縮文件的圖片。改後綴名能夠正常解壓,改成圖片格式又能夠正常預覽。
簡單的說就是把圖片與壓縮文件用二進制的方式合併起來。圖片數據在前,壓縮文件數據在後。python

雖然Batch腳本一條語句就能夠生成,可是咱們要講究批量和自動化嘛,因此用python來實現。多線程

1. 設置任務列表

  • 建立一個Import文件夾,將要處理的圖片和壓縮包放進去。
  • 與壓縮包同名的圖片將優先和壓縮包合併,沒有則與默認圖片default.*合併,沒有放入默認圖片則自動生成黑色圖片與之合併。
  • 支持的圖片格式:*.jpg*.png*.bmp
  • 支持的壓縮格式:*.rar*.zip*.7z
# -*- coding: utf-8 -*-
# python 3.7.2

import os
import io

from timeit import timeit

#
from PIL import Image
from concurrent.futures import ThreadPoolExecutor

# ---
ALL_TASK= []
IMPORT_FOLDER= 'Import/'
EXPORT_FOLDER= 'Export/'
# ---


def SetTaskList():
    global ALL_TASK
    ALL_TASK= []
    if not os.path.exists(EXPORT_FOLDER):
        os.makedirs(EXPORT_FOLDER)
    
    files= os.listdir(IMPORT_FOLDER)
    default_img= ['default'+i for i in ('.jpeg','.jpg','.png','.bmp')]
    ImgM= None
    ext= '.jpeg'
    # 判斷是否存在默認圖,沒有則自動建立
    for img in default_img:
        if img in files:
            ImgM= Image.open(IMPORT_FOLDER+img)
            ext= os.path.splitext(img)[1]
            ext= '.jpeg' if ext=='.jpg' else ext
            files.remove(img)
            break
    if not ImgM:
        ImgM= Image.new('L', (32,32), (60,))
        
    # 第一行寫入圖片擴展名
    ImgM_Bytes= io.BytesIO()
    ImgM_Bytes.write(ext.encode()+ b'\n')
    ImgM.save(ImgM_Bytes, ext[1:])

    # 判斷是否有對應的'同名字'圖片,沒有則與默認圖合成
    for f in files:
        split= os.path.splitext(f)
        if split[1].lower() in ('.rar','.zip','.7z'):
            imgs= [split[0]+i for i in ('.jpeg','.jpg','.png','.bmp')]
            cover_image= None
            for img in imgs:
                if img in files:
                    cover_image= img
                    break
            
            ALL_TASK.append((f,cover_image or ImgM_Bytes))


2. 多線程分配任務

def AssignTask():
    pool = ThreadPoolExecutor()
    results = list(pool.map(CreateImgSeed, ALL_TASK))
    pool.shutdown()
    
    print ('{}個圖種製做完畢!'.format(len(ALL_TASK)))


3. 建立圖種

  • 用二進制格式打開
  • 最終輸出文件以壓縮包名字命名,保持對應圖片擴展名
def CreateImgSeed(task):
    pack, img= task
    with open(IMPORT_FOLDER+pack,'rb') as p:
        if type(img)==str:
            with open(IMPORT_FOLDER+img, 'rb') as i:
                ext= os.path.splitext(img)[1]
                img_data= i.read()
        else:
            datas= img.getvalue()
            i= datas.index(b'\n')
            ext= datas[:i].decode()
            img_data= datas[i+1:]
                
        # 最終輸出文件以壓縮包名字命名,保持對應圖片擴展名
        out_file= open(EXPORT_FOLDER + os.path.splitext(pack)[0] + ext, 'wb')
        out_file.write(img_data)
        out_file.write(p.read())
        out_file.close()



完整代碼

  • ImgSeed.py
# -*- coding: utf-8 -*-
# python 3.7.2

import os
import io

from timeit import timeit

#
from PIL import Image
from concurrent.futures import ThreadPoolExecutor

# ---
ALL_TASK= []
IMPORT_FOLDER= 'Import/'
EXPORT_FOLDER= 'Export/'
# ---


def SetTaskList():
    global ALL_TASK
    ALL_TASK= []
    if not os.path.exists(EXPORT_FOLDER):
        os.makedirs(EXPORT_FOLDER)
    
    files= os.listdir(IMPORT_FOLDER)
    default_img= ['default'+i for i in ('.jpeg','.jpg','.png','.bmp')]
    ImgM= None
    ext= '.jpeg'
    # 判斷是否存在默認圖,沒有則自動建立
    for img in default_img:
        if img in files:
            ImgM= Image.open(IMPORT_FOLDER+img)
            ext= os.path.splitext(img)[1]
            ext= '.jpeg' if ext=='.jpg' else ext
            files.remove(img)
            break
    if not ImgM:
        ImgM= Image.new('L', (32,32), (60,))
        
    # 第一行寫入圖片擴展名
    ImgM_Bytes= io.BytesIO()
    ImgM_Bytes.write(ext.encode()+ b'\n')
    ImgM.save(ImgM_Bytes, ext[1:])

    # 判斷是否有對應的'同名字'圖片,沒有則與默認圖合成
    for f in files:
        split= os.path.splitext(f)
        if split[1].lower() in ('.rar','.zip','.7z'):
            imgs= [split[0]+i for i in ('.jpeg','.jpg','.png','.bmp')]
            cover_image= None
            for img in imgs:
                if img in files:
                    cover_image= img
                    break
            
            ALL_TASK.append((f,cover_image or ImgM_Bytes))
    
    
def CreateImgSeed(task):
    pack, img= task
    with open(IMPORT_FOLDER+pack,'rb') as p:
        if type(img)==str:
            with open(IMPORT_FOLDER+img, 'rb') as i:
                ext= os.path.splitext(img)[1]
                img_data= i.read()
        else:
            datas= img.getvalue()
            i= datas.index(b'\n')
            ext= datas[:i].decode()
            img_data= datas[i+1:]
                
        # 最終輸出文件以壓縮包名字命名,保持對應圖片擴展名
        out_file= open(EXPORT_FOLDER + os.path.splitext(pack)[0] + ext, 'wb')
        out_file.write(img_data)
        out_file.write(p.read())
        out_file.close()


def AssignTask():
    pool = ThreadPoolExecutor()
    results = list(pool.map(CreateImgSeed, ALL_TASK))
    pool.shutdown()
    
    print ('{}個圖種製做完畢!'.format(len(ALL_TASK)))
    
    
def start():
    SetTaskList()
    sec = timeit(lambda:AssignTask(),number=1)
    print ('Time used: {0:.3f} sec\n'.format(sec))
    s= input('按回車鍵退出...\n')
    
    
    
if __name__ == '__main__':
    while True:
        s= input('開始製做圖種(Y/N): ')
        if s.lower()== 'y':
            start()
            break
        elif not s or s.lower()== 'n':
            break
相關文章
相關標籤/搜索