欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python - 批量制作图种

程序员文章站 2022-03-22 11:21:52
什么是图种,就是一种包含压缩文件的图片。改后缀名可以正常解压,改为图片格式又可以正常预览。 ......

  什么是图种,就是一种包含压缩文件的图片。改后缀名可以正常解压,改为图片格式又可以正常预览。
简单的说就是把图片与压缩文件用二进制的方式合并起来。图片数据在前,压缩文件数据在后。

虽然batch脚本一条语句就可以生成,但是我们要讲究批量和自动化嘛,所以用python来实现。

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