【IRIS/Cache】画像ファイルの操作(読み・書き)

今回は画像ファイルの読み書きについて解説いたします。

画像ファイルの操作を行いたい方は、この記事を一読していただけると幸いです。

※この記事は下記の方向けになります。
  • 画像ファイルを読み込んだ事がないユーザ
  • データから画像を作成したことがないユーザ

はじめに

画像ファイルをデータで持つか、ファイルで持つかに関してはどちらにも利点があり、システムの構造によって選択する事になると思います。

今回は、画像ファイルをデータとして保存する方法と、その保存したデータを再度画像ファイルにする方法を記載いたします。

画像ファイルをデータ化する

画像ファイルをデータ化するには、「%File」を利用します。

次のサンプルは、「%File」を使用した画像ファイルの読み込みサンプルになります。

関数「Open」の引数に「LRUK\BIN\」を渡します。
 →L:排他ロック、R:読み取り、U:未定義の長さ、K\BIN\:I/O変換モード

Class developer.img.Sample
{

ClassMethod read(basePath As %String)
{
	try {
		k ^ImgDt
		s file = ##class(%File).%New(basePath)
  		$$$ThrowOnError( file.Open("LRUK\BIN\") )
		while ( 'file.AtEnd ){
			s line = file.Read(10000, .sts)
			$$$ThrowOnError(sts)
			continue:(line="")
			s ^ImgDt($i(^ImgDt))=line
		}
		d file.Close()		
	}catch e {
		w !,$system.Status.DisplayError(e.AsStatus())
	}
}

}

では読み込んでみましょう。
下記コマンドをターミナルから実行します。

d ##class(developer.img.Sample).read("D:\Temp\img\title.jpg")

実行結果を確認します。
サンプル画像では、文字数が126,645文字になりました。

また、取得したデータをbase64に変換して保存する事も可能です。
base64では76文字毎に改行コードが入るので、同じ画像ファイルでも文字数が増加し、173,324文字になります。

s ^ImgDt($i(^ImgDt))=$system.Encryption.Base64Encode(line)

base64は使い勝手が良いので、どちらの状態で画像データを保持するかはシステム次第ですかね。

データを画像ファイルにする

相手データベースからバイナリデータを取得し、画像ファイルとして保存する業務があったので、備忘的に記載します。

サンプルは下記になります。
画像データをファイル化するには、「%FileBinaryStream」を利用します。

データを詰め込んで保存の流れなので、とてもシンプルです。

Class developer.img.Sample
{

ClassMethod make(filePath As %String)
{
	try{
		s file = ##class(%FileBinaryStream).%New()
		d file.LinkToFile(filePath)
		f pos = 1:1:^ImgDt {
			d file.Write(^ImgDt(pos))
		}
		$$$ThrowOnError( file.SaveStream() )
        k ^ImgDt
	}catch e {
		w !,$system.Status.DisplayError(e.AsStatus())
	}
}

}

では、画像データをファイル化しましょう。
下記コマンドを実行します。

d ##class(developer.img.Sample).make("D:\Temp\img\copy.jpg")

画像ファイルが出来たら、元の画像と同じである事を確認してみてください。
また、拡張子も同一のはずです。

base64をバイナリデータに戻すのであれば、下記コマンドを利用します。

d file.Write($system.Encryption.Base64Decode(^ImgDt(pos)))

おわりに

ユーザ操作の画像アップロードで、サーバ側にbase64にエンコードされた画像ファイルのバイナリデータが送られてきた時、画像ファイルをどう保存するか?で悩んだ事があります。

データなのか、ファイルなのか、これは難しい判断ですよね。
どちらにしても、対応方法さえ知っていれば問題ないと思います。

何かのお役に立てれれば幸いです。