HEICファイルとは
HEICファイル(High Efficiency Image File Format)とは新しい画像形式で、iOS 11から採用されている、ファイル形式です。
画質はそのままにJPEGファイルの半分くらいのファイルサイズとなるように設計されているようです。
HEICファイルの説明についての日本語の記事だと、下記のポストが分かりやすそうでしたので貼っておきます。
sipsを使ってHEICファイルをJPEGファイルに変換する
macには標準でsips
というコマンドがついています。
使い方については
sips --help
で見るのが手っ取り早いです。
また、使い方の例として記事下部の参照欄にsips
コマンドについて書かれている方の記事を貼らせていただきました。
このsips
を使って、HEICからjpegに変換していきます
コマンドライン上で実行するなら、下記でOKです。
sips --setProperty format jpeg hogehoge.HEIC --out hogehoge.jpeg
これでhogehoge.HEIC
をhogehoge.jpeg
に変換できます。
今回は、ディレクトリ単位でまとめてHEIC
からjpeg
に変換するPythonスクリプトを書いてみました。
from os import path
from glob import glob
import subprocess
CURRENT_PATH = path.dirname(path.abspath(__file__))
WORK_DIR = 'work' # 変換対象のディレクトリ
RESULT_DIR = 'result' # JPEGに変換したファイルを格納するディレクトリ
files = [r.split('/')[-1] for r in glob(path.join(CURRENT_PATH, WORK_DIR,'*.HEIC'))]
for f in files:
inputFile = path.join(CURRENT_PATH, WORK_DIR, f)
outputFile = path.join(CURRENT_PATH, RESULT_DIR, f.replace('.HEIC','.jpeg'))
command = 'sips --setProperty format jpeg ' + inputFile + ' --out ' + outputFile
print(command)
subprocess.call(command, shell=True)
やはりJPEG
に変換するとファイル容量も2倍近くに増えるようです。
画像をリサイズしながら、jpegに変換する
sips
コマンドの中でアスペクト比を変えずにリサイズする方法がありましたので、今回はそれをそのままに使います。
オプションで -Z {リサイズ値}
でアスペクト比を保ったまま、リサイズしてくれるようです。
先程のPythonスクリプトを修正します。
横が 1024px
になるようにリサイズしたいので、下記のように修正します。
from os import path
from glob import glob
import subprocess
CURRENT_PATH = path.dirname(path.abspath(__file__))
WORK_DIR = 'work' # 変換対象のディレクトリ
RESULT_DIR = 'result' # JPEGに変換したファイルを格納するディレクトリ
files = [r.split('/')[-1] for r in glob(path.join(CURRENT_PATH, WORK_DIR,'*.HEIC'))]
for f in files:
inputFile = path.join(CURRENT_PATH, WORK_DIR, f)
outputFile = path.join(CURRENT_PATH, RESULT_DIR, f.replace('.HEIC','.jpeg'))
command = 'sips -Z 1024 --setProperty format jpeg ' + inputFile + ' --out ' + outputFile
print(command)
subprocess.call(command, shell=True)
画像を収縮させると、一気にファイルサイズも減ります。
JPEGに変換した上でEXIF情報も削除したい
sips
コマンドの中でEXIF
情報も併せて削除できないものかと思い、調べてみましたが、できなそうでした。
大変ありがたいことにコメントを頂き、sips
コマンドの中で完結できることができました!!
https://qiita.com/shinshin86/items/ae896113e97a0b8e4f94#comment-16864547d761e2ed88b3
sips
コマンドで完結させるやり方は、下記のsipsコマンドだけを用いて、JPEGに変換した上でEXIF情報も削除したい
に書きましたので、そちらをご参照ください
そのため、Exif情報の削除についてはPythonのライブラリであるPillow
を使って処理を書いていくことにしました。
下記のスクリプトを実行することで、以下3つの処理を実施します
-
sips
からjpeg
への変換 - 画像を幅
1024px
にリサイズ -
Exif
情報を削除
from os import path
from glob import glob
import subprocess
from PIL import Image
from PIL.ExifTags import TAGS
CURRENT_PATH = path.dirname(path.abspath(__file__))
WORK_DIR = 'work' # 変換対象のディレクトリ
RESULT_DIR = 'result' # JPEGに変換したファイルを格納するディレクトリ
files = [r.split('/')[-1] for r in glob(path.join(CURRENT_PATH, WORK_DIR,'*.HEIC'))]
for f in files:
inputFile = path.join(CURRENT_PATH, WORK_DIR, f)
outputFile = path.join(CURRENT_PATH, RESULT_DIR, f.replace('.HEIC','.jpeg'))
try:
command = 'sips -Z 1024 --setProperty format jpeg ' + inputFile + ' --out ' + outputFile
print(command)
subprocess.call(command, shell=True)
ret = {}
targetFile = Image.open(outputFile)
info = targetFile._getexif()
if(info == None):
print("This file does not process : " + file)
continue
for tag, value in info.items():
decoded = TAGS.get(tag, tag)
ret[decoded] = value
ret['XResolution'] = 0
ret['WhiteBalance'] = 0
ret['ResolutionUnit'] = 0
ret['SubsecTimeOriginal'] = 0
ret['Model'] = 0
ret['Orientation'] = 0
ret['DateTimeDigitized'] = 0
ret['ExposureMode'] = 0
ret['DateTime'] = 0
ret['YResolution'] = 0
ret['Make'] = 0
ret['ComponentsConfiguration'] = 0
ret['ApertureValue'] = 0
ret['ColorSpace'] = 0
ret['ExposureProgram'] = 0
ret['FNumber'] = 0
ret['ShutterSpeedValue'] = 0
ret['MeteringMode'] = 0
ret['LensModel'] = 0
ret['LensMake'] = 0
ret['ExifVersion'] = 0
ret['FlashPixVersion'] = 0
ret['FocalLength'] = 0
ret['ExposureTime'] = 0
ret['SensingMethod'] = 0
ret['MakerNote'] = 0
ret['ExifOffset'] = 0
ret['SubjectLocation'] = 0
ret['FocalLengthIn35mmFilm'] = 0
ret['Software'] = 0
ret['Flash'] = 0
ret['ISOSpeedRatings'] = 0
ret['SubsecTimeDigitized'] = 0
targetFile.save(outputFile)
targetFile.close()
print("=== SUCCESS => ", outputFile)
except Exception as ex:
print("=== ERROR => This file cannot be processed!! ===")
print("FILE NAME : " + f)
print(ex)
print("================================================")
ちなみに、EXIF
情報の削除部分については、手前味噌ですが、自身で元々書いていたEXIF
削除用のPythonスクリプト内での処理をほぼほぼそのまま流用しています。
shinshin86/Delete-Exif(Github)
(cli
とweb
、2つのバージョンがこのリポジトリにはあるのですが、わかりにくいので、後々リポジトリ内の構成を整理しようかと思っています。)
sipsコマンドだけを用いて、JPEGに変換した上でEXIF情報も削除したい
コメント頂きました @KEINOS さんに感謝です!
https://qiita.com/shinshin86/items/ae896113e97a0b8e4f94#comment-16864547d761e2ed88b3
一旦 EXIF を持たないロスレス画像(PNG や BMP など)に変換してから JPEG にしてはどうでしょう?
EXIFを持たない画像を経由してからJPEG
に変換することで、EXIF情報の削除が行えるのは、目からウロコでした。とても勉強になりました。
というわけで、sips
コマンドのみを用いてjpeg変換&exif削除
を実現したコードは下記となります。
#!/bin/bash
WORKDIR='work'
RESULTDIR='result'
for heicfile in $(ls $WORKDIR/*.HEIC); do
bmpfile=${heicfile%.HEIC}.bmp
jpegfile=${heicfile%.HEIC}.jpeg
bmpfile_path=$RESULTDIR/${bmpfile##*/}
jpegfile_path=$RESULTDIR/${jpegfile##*/}
sips --setProperty format bmp $heicfile --out $bmpfile_path && sips --setProperty format jpeg $_ --out $jpegfile_path && rm $bmpfile_path
done
ちなみにリサイズを行いたいときは-Z {リサイズしたい幅}
をsips
コマンドのオプションとして渡せばよいだけなので、下記のようになりますね!
(幅を1024px
にリサイズしたいとき)
#!/bin/bash
WORKDIR='work'
RESULTDIR='result'
for heicfile in $(ls $WORKDIR/*.HEIC); do
bmpfile=${heicfile%.HEIC}.bmp
jpegfile=${heicfile%.HEIC}.jpeg
bmpfile_path=$RESULTDIR/${bmpfile##*/}
jpegfile_path=$RESULTDIR/${jpegfile##*/}
sips -Z 1024 --setProperty format bmp $heicfile --out $bmpfile_path && sips --setProperty format jpeg $_ --out $jpegfile_path && rm $bmpfile_path
done
まとめ: sipsコマンド便利、Linuxだとimagemagick?
sips
はmac環境でしか使えないコマンドですが、かなり便利なコマンドですね。
Linux
環境になると、sips
の代替コマンドはimagemagick
とかになるのでしょうか?
imagemagick
の様々な使い方が書かれているポストを見つけたので、こちらを最後に貼っておきます。
How to Quickly Resize, Convert & Modify Images from the Linux Terminal
参照
macOS Mojave の標準コマンドで Jpeg 画像を PNG に変換するワンライナー
shinshin86/Delete-Exif(Github)
How to Quickly Resize, Convert & Modify Images from the Linux Terminal