今回は画像ファイルの読み書きについて解説いたします。
画像ファイルの操作を行いたい方は、この記事を一読していただけると幸いです。
はじめに
画像ファイルをデータで持つか、ファイルで持つかに関してはどちらにも利点があり、システムの構造によって選択する事になると思います。
今回は、画像ファイルをデータとして保存する方法と、その保存したデータを再度画像ファイルにする方法を記載いたします。
画像ファイルをデータ化する
画像ファイルをデータ化するには、「%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にエンコードされた画像ファイルのバイナリデータが送られてきた時、画像ファイルをどう保存するか?で悩んだ事があります。
データなのか、ファイルなのか、これは難しい判断ですよね。
どちらにしても、対応方法さえ知っていれば問題ないと思います。
何かのお役に立てれれば幸いです。