python 实现43中图片格式任意互转 包括icns、heic、heif

2020-03-20 发表在 编程语言 690

需要安装依赖

pip install pillow
yum install imagemagick
import io

from PIL import Image

import os

import subprocess
import uuid


def _incs(im):
    # icns最小500
    w, h = im.size
    if w < 500 or h < 500:
        im = im.resize((500, 500))

    return im


def handler_heif(im, fp, filename):
    r = subprocess.Popen(['magick', im.filename, filename])
    result = r.wait()
    if result != 0:
        raise Exception('out heic error.')

    if isinstance(fp, io.BytesIO):
        with open(filename, 'rb') as f:
            fp.write(f.read())
        # 删除临时文件
        os.remove(filename)


def read_heif(br, file):
    # 原始文件写入png 然后加载到内存
    _temp_file_name = "_temp_{}{}".format(uuid.uuid4(), os.path.splitext(file)[1])

    temp_file = os.path.join(os.path.dirname(file), _temp_file_name)

    r = subprocess.Popen(['magick', file, temp_file])
    if r.wait() != 0:
        raise Exception('read heic error.')
    bytesio = io.BytesIO()
    with open(temp_file, 'rb') as f:
        bytesio.write(f.read())
    os.remove(temp_file)

    return Image.frombytes(bytesio)


def convert(source, t_suffix):
    """

    :param source:
    :param target:
    :return:
    """

    if not os.path.exists(source):
        raise Exception('file not found.{}'.format(source))
    supports = ['bmp', 'dib', 'eps', 'gif', 'icns', 'ico', 'im', 'jpeg', 'msp', 'pcx', 'png', 'ppm', 'sgi',
                'spider', 'tga', 'tiff', 'webp', 'xbm', 'heic', 'heif']

    s_suffix = os.path.splitext(source)[1][1:].upper()

    if s_suffix in ['heic', 'heif']:
        Image.register_open('heic', read_heif)
        Image.register_open('heif', read_heif)

    # 保存不能heif和heic

    Image.register_save('heic', handler_heif)
    Image.register_extension('heic', '.heic')

    Image.register_save('heif', handler_heif)
    Image.register_extension('heif', '.heif')

    im = Image.open(source)

    """
    1,L,P,RGB,RGBA,CMYK,YCbCr,I, F
    模式"1"为二值图像,非黑即白。但是它的每个像素用8个bit表示,0表示黑,255表示白。
    模式"L"为灰度图像,它的每个像素用8个bit位表示,其中0表示黑,255表示白,其它数字表示不同的灰度。在PIL模式中, 从模式"RGB"转换到模式"L",有一个计算公式,即:L = R * 299/1000 + G * 587/1000+ B * 114/1000(只取整数部分)。
    模式"P"为8位彩色模式,它的每一个像素用8个bit表示, 其对应的色彩是按照调色板查询出来的。
    模式"RGBA"为32位彩色模式,其中24个bit分别表示红色,绿色,蓝色三个通道,另外8个bit 表示alpha通道,即透明通道。
    模式“CMYK”为32位彩色图像,它的每个像素用32个bit表示。模式“CMYK”就是印刷四分色模式,它是彩色印刷时采用的一种套色模式,利用色料的三原色混色原理,加上黑色油墨,共计四种颜色混合叠加,形成所谓“全彩印刷”。四种标准颜色是:C:Cyan = 青色,又称为‘天蓝色’或是‘湛蓝’M:Magenta = 品红色,又称为‘洋红色’;Y:Yellow = 黄色;K:Key Plate(blacK) = 定位套版色(黑色)。
    模式“YCbCr”为24位彩色图像,它的每个像素用24个bit表示。YCbCr其中Y是指亮度分量,Cb指蓝色色度分量,而Cr指红色色度分量。人的肉眼对视频的Y分量更敏感,因此在通过对色度分量进行子采样来减少色度分量后,肉眼将察觉不到的图像质量的变化。
    模式"I"为32位整型灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式"RGB"转换为"I"模式是按照下面的公式转换的:I = R * 299/1000 + G * 587/1000 + B * 114/1000
    模式"F"为32位浮点灰色图像,它的每个像素用32个bit表示,0表示黑,255表示白,(0,255)之间的数字表示不同的灰度。在PIL中,从模式"RGB"转换为"F"模式是按照下面的公式转换的: F = R * 299/1000+ G * 587/1000 + B * 114/1000 模式"F"与模式"L"的转换公式是一样的,都是RGB转换为灰色值的公式,但模式"F"会保留小数部分。
    """
    if t_suffix == 'ICNS':
        _incs(im)

    if t_suffix in ['MSP', 'XBM', 'PALM']:
        im = im.convert('1')
    bi = io.BytesIO()
    bi.name = '/Users/panjing/Downloads/image/_temp_{}.{}'.format(uuid.uuid4(), s_suffix)
    im.save(bi, t_suffix)
    return bi


if __name__ == '__main__':
    # 43种格式互转
    supports = ['heic', 'heif', 'bmp', 'dib', 'gif', 'tif', 'tiff', 'jfif', 'jpe', 'jpg', 'jpeg', 'pbm', 'pgm', 'ppm',
                'pnm', 'png', 'apng', 'pcx', 'ps', 'eps', 'jp2', 'j2k', 'jpc', 'jpf', 'jpx', 'j2c', 'icns', 'ico', 'im',
                'mpo', 'msp', 'palm', 'pdf', 'bw', 'rgb', 'rgba', 'sgi', 'tga', 'icb',
                'vda', 'vst', 'webp', 'xbm']
    print(len(supports))

    bi = convert('/Users/panjing/Downloads/image/ag.png', 'gif')

    print(bi)

文章来源:https://www.88cto.com/article/XpuPdyTT

作者:贝塔博客
本站使用「署名 4.0 国际」创作共享协议,转载请在文章明显位置注明作者及出处。
评论
登录以后才可以发布评论哦, 点击登录 发布评论
评论列表 0人参与,0条评论
暂时还没有人评论,快来一条神回复吧!