Colaboratory環境で拡張子が.HEICの画像ファイルを扱う(libheif,pyheif)

本記事では、iPhoneで撮影した画像など、拡張子が.HEICになっている画像ファイルをGoogle Colaboratory内で直接扱う方法を考えてみました。

【目次】

[1]拡張子が.HEICの画像ファイルとは?

拡張子が.HEICとなっているファイルは、HEIFという新しい標準規格の画像ファイルです。(HEIF仕様のファイル拡張子は、.heifあるいは.heicです。また、HEIFはヒーフと読むみたいです。)

iOS 11以降のiPhoneなどで新しく撮影した写真は、HEIFに対応して拡張子が、.HEICとして保存されます。(但し、設定によりHEIFではなくJPEGで保存することも可能です。)

HEIFは、JPEGに比べて高画質なままファイルサイズを小さくできる、などのメリットがあります。

iPhoneなどを使っていると、HEICという拡張子を目にする機会は少ないと思いますが、GoogleフォトやGoogleドライブ、そしてWindowsなどに画像ファイルを転送すると、その画像ファイルの拡張子が.HEICになっていることを確認できます。

Windows 10もHEIFに対応しており、HEICファイルをダブルクリックすると、フォトが起動して画像を表示します。

また、ペイントでHEICファイルを読み込んで、PNG画像またはJPEG画像として名前を付けて保存すると、PNGやJPG形式のファイルに変換することが出来ます。この変換したPNGやJPEGファイルのサイズがHEICファイルに比べて大きくなることから、HEIFの圧縮効率が良いことがうかがえます。

[2]JPEGファイルなどに変換が必要な理由

HEICファイルにはメリットもありますが、比較的新しい画像フォーマットということもあり、何らかの処理を行おうとすると不便なこともあります。

例えば、PillowやOpenCV等の画像処理ライブラリを利用したい場合、現在のところHEICファイルを直接読み込むことができません。このため、ライブラリが認識できる画像形式にあらかじめ変換して利用する必要があります。

また、『Google Vision APIの画像認識(特にOCR)を業務システム開発の立場から検討してみる』からの流れで、Vision APIを試してみようとしても、残念ながら、現在のところVision APIはHEIC形式をサポートしていないため、JPEGやPNG形式などに変換してから利用する必要があります。

HEICファイルをJPEGファイルなどに変換する方法はネットで検索すると様々な情報が得られますが、ここでは、『Colaboratory+GoogleドライブでVision APIの実験環境を作る』の流れから、Colaboratoryの環境内で直接HEICファイルを扱う方法を考えてみました。

以降は、
  • シェルコマンドでJPEGまたはPNGに変換する方法
  • Python言語でHEICファイルを扱う方法
について具体的に説明していきます。

なお、上記二つの方法は、組み合わせて利用することもできます。

(補足)

下記サンプルは、Googleドライブをマウントして、Googleドライブにある画像を処理する例となっています。Googleドライブのマウントについては、『Colaboratory+GoogleドライブでVision APIの実験環境を作る/Googleドライブのマウント』を参照してください。
Colaboratoryのディスクで処理する場合はGoogleドライブのマウントは不要です。

[3]シェルコマンドでJPEGまたはPNGに変換する方法

(1)libheif

libheifはオープンソースで提供されている、HEIFとAVIFファイル形式のデコーダ、エンコーダライブラリです。

libheifをColaboratoryから直接利用して画像変換することはできませんが、大変ありがたいことに、libheifを使ってHEICファイルをJPEGまたはPNGファイルに変換するユーティリティプログラム(heif-converter)が提供されています。
heif-converterは、OSレベルでlibheif-examplesパッケージをインストールすることで、シェルコマンドから利用することが出来ます。

(2)libheif-examplesのインストール

Colaboratoryはaptコマンドが利用できますので、以下のセルを実行することで、libheif-examplesをインストールすることが出来ます。
!apt install libheif-examples

(補足)
インストールされるライブラリのバージョンは、1.1.0-2になると思います。Colaboratoryから、!cat /etc/lsb-release コマンドでOSのバージョンを調べると、"Ubuntu 18.04.3 LTS"と表示されましたので、インストールされたパッケージは、(https://packages.ubuntu.com/bionic/video/libheif-examples)に該当すると思います。
なお、このバージョンはGitHubで公開されているものに比べると少し古く、最新版ではユーティリティプログラムが追加されていますが、JPEGやPNG形式に変換するだけなら上記手順でインストールして利用するのが便利です。

(3)heif-convertを使ってJPEGまたはPNGに変換

HEICファイルをJPEGまたはPNGファイルに変換するには、シェルコマンドでheif-convertを利用します。

使い方は簡単で、元のHEICファイルパスと出力したいJPEGまたはPNGファイルパスを指定するだけです。
例えば、Googleドライブの直下にあるsample.HEICをJPEGファイルに変換したい場合は、出力ファイル名の拡張子をjpgにして実行します。
!heif-convert '/content/drive/My Drive/sample.HEIC' '/content/drive/My Drive/sample.jpg'

同様に、PNGファイルに変換したい場合は、出力ファイル名の拡張子をpngにして実行します。
!heif-convert '/content/drive/My Drive/sample.HEIC' '/content/drive/My Drive/sample.png'

(補足1)

ファイルを指定せずheif-convertを実行すると利用方法が表示されます。
!heif-convert
 
USAGE: heif-convert [-q quality] <filename> <output>

ここで、-q はJPEGの品質設定で、0から100の値を設定します。値が大きいほうが品質が良くなりますが、逆にファイルサイズも大きくなります。
(現在のGitHubのソースを見ると、-qを省略した場合の値は90のようです。)

品質設定を変更して画質やファイルサイズを調整したい場合は(例えば、品質設定に80を指定する場合は、)以下のように実行します。
!heif-convert -q 80  '/content/drive/My Drive/sample.HEIC' '/content/drive/My Drive/sample.jpg'

(補足2)

heif-examplesには、heif-infoという、HEICファイルの情報を表示するプログラムも含まれています。以下のように利用します。
!heif-info  '/content/drive/My Drive/sample.HEIC'

[4]Python言語でHEICファイルを扱う方法

(1)pyheif

pyheifは、libheifライブラリへのPythonインターフェイスライブラリです。

heif-convertのようなシェルコマンドは提供されていませんが、Python言語からHEICファイルを読み込んで、Pillowなどのライブラリに画像データを渡すことが出来るため、JPEGやPNGファイルなどへの形式変換だけでなく、様々な画像処理を行うことができるため、応用範囲は広いです。

なお、libheif-examplesとpyheifの両方をインストールして個別に利用することも可能です。

(2)pyheifのインストール

インストールは簡単で、以下のセルを実行するだけです。
!pip install pyheif

(3)pyheifの利用例:JPEGまたはPNGに変換

現在のところpyheifは読込しか対応していませんが、読み込んだ画像データをPillow等の画像処理ライブラリに渡すことで、様々な処理を行うことができます。

何の工夫もないサンプルで恐縮ですが、pyheifのサイトにあるサンプルを使って、heic-convertのように、HEICファイルをJPEGまたはPNGファイルに変換する関数を書くと以下のようになります。(出力ファイルの拡張子により出力画像形式を判断します。)

def heic_convert_to(heic_filename, output_filename,q=90):
  import pyheif
  from PIL import Image

  heif = pyheif.read(heic_filename)

  image = Image.frombytes(
              heif.mode, 
              heif.size, 
              heif.data,
              "raw",
              heif.mode,
              heif.stride,
          )

  image.save(output_filename,quality=q )

このような変換関数を定義しておくと、Colaboratoryから簡単に変換が行えるようになります。

例えば、jpgに変換する場合は以下のようになります。(JPEGの品質設定は初期値の90)
heic_convert_to('/content/drive/My Drive/sample.HEIC','/content/drive/My Drive/sample.jpg')

JPEGの品質設定に80を指定する場合は以下のようになります。
heic_convert_to('/content/drive/My Drive/sample.HEIC','/content/drive/My Drive/sample.jpg',80)

pngへの変換も同様に拡張子にpngを指定します。
heic_convert_to('/content/drive/My Drive/sample.HEIC','/content/drive/My Drive/sample.png')

なお、このようなユーティリティ関数はモジュールとしてGoogleドライブで管理しておくと複数のノートブックで共有できて便利です。

コメント

このブログの人気の投稿

VirtualBoxのスナップショット機能

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

Ubuntu/Colab環境でPDFファイルのページを画像化する(pdf2image、pdftoppm、pdftocairo)