近期自网上下载的许多jpg格式图片,在PS和opencv中都无法打开,在查看图片格式信息时,才发现这些图片实际格式是heif/heic,而不理其扩展名所示的jpeg格式。在网上找了一些解决办法,包括一些AI给出的解决方案都无法解决这种以jpg文件扩展名的heif图片格式转换问题。综合各方方案,现将个人方案发布,供大家参考。
# -*- coding:utf8 -*-
import os
import glob
import shutil
import whatimage
import pillow_heif
from PIL import Image as pilImage
import argparse
gSrcPath=None
gDestPath=None
gShowInfo=False
def getPicFromDir(picPath):
'''获取指定目标下的所有picture文件列表'''
if not os.path.isdir(picPath):
return None
ext_names = ['.jpg', '.png', '.jpeg','*.webp','*.bmp','*.gif']
allImgs=[]
for ext in ext_names:
filenams=os.path.abspath(os.path.join(picPath,"./*%s" % ext))
allImgs.extend(glob.glob(filenams))
if len(allImgs)!=0 :
return allImgs
else:
return None
def convert_heic_jpg(src_img_path):
dest_img_path=os.path.join(gDestPath,os.path.basename(src_img_path))
with open(src_img_path, 'rb') as f:
heic_img = f.read()
# 获取图征文件格式
img_format = whatimage.identify_image(heic_img)
if gShowInfo:
print(f'{os.path.basename(src_img_path)} Image format:{img_format}')
if img_format in ['heic']:
img = pillow_heif.read_heif(heic_img)
pi = pilImage.frombytes(mode=img.mode, size=img.size, data=img.data)
fn,_=os.path.splitext(dest_img_path)
pi.save(fn+'.jpg', format="jpeg")
else:
try:
shutil.copyfile(src_img_path,dest_img_path)
except Exception as e:
print("复制文件发生错误:", str(e))
if __name__ == '__main__':
argp=argparse.ArgumentParser(description='heif格式图片转换成jpeg格式')
argp.add_argument('src_path',help='指定源图片文件所在文件目录')
argp.add_argument('dest_path',help='指定保存转换后图片文件目录')
argp.add_argument('-V','--verbose',action='store_true',help='显示详细信息')
try:
args=argp.parse_args()
except:
exit(2)
gSrcPath=args.src_path
gDestPath=args.dest_path
gShowInfo=args.verbose
if os.path.isdir(gSrcPath) and os.path.isdir(gDestPath):
pics=[]
pics=getPicFromDir(gSrcPath)
if pics:
for f in pics:
convert_heic_jpg(f)
else:
print(f'{gSrcPath}目录中没有包含图片文件,请确保其中包含jpg, png, jpeg等后缀的图片文件。')
exit(1)
else:
print(f'{gSrcPath} 或 {gDestPath} 目录指定不正确。')
exit(1)
需要说明的是,imghdr无法准确判断以.jpg为文件扩展名的heif图片格式文件,而我在环境安装pyheif时出现编译错误,而用whatimage和pillow_heif则正确完成转换目的。这断代码是将一个目录中的所有heif/heic图片文件转换成jpeg格式,并保存在另一个目录中,对于非heif/heic格式文件,则只是简单复制到另一个目录中。