This page (revision-1) was last changed on 20-Apr-2024 11:53 by Hiroaki Tateshita

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Page revision history

Version Date Modified Size Author Changes ... Change note
20-Apr-2024 11:53 4 KB Hiroaki Tateshita

Page References

Incoming links Outgoing links

Version management

Difference between version and

At line 1 added 68 lines
[{PageViewPlugin}]
[Dev Record GeoPicPlugin], [GeoPicPlugin]
!!!Abstract
画像ファイルをアップロードするときにファイルサイズを小さくしたい。
!!!Topics
!!やりたいこと
*GeoPicPluginでファイルサイズを抑えた写真ファイルのアップロードをしたい。ただし、本当に制限したいファイルサイズも指定したい。例えば、50Mのファイルはダメとか。
!!記録
*まずファイルの扱いをフローにしたい。
|アップロードボタンが押されてから、まず、サーバにファイルがアップロードされて、そのあとEXIFを読み取るのが今回のプログラムかな。保存のタイミングはどこか。
|GeoPicServlet.upload()の175ライン当たりにparseRequestというのがあり、ここで”本当に制限したいファイルサイズ”のチェックがされる。
|GeoPicServlet.upload()の250ラインあたりに(FileItem)actualFileオブジェクトができている。そこから情報を吸い出しているようだ。InputStreamもそこからいつでも得られる。このInputStreamからEXIFなどを吸い出して、Fileを更新して一次フォルダに保管しておいて、ファイルアップロードを実行するときには一次保管したファイルのInputStreamを渡す。
|315行あたりにthis.executeUpload(,InputStream in,)とある。
|467行あたりにm_engine.getAttachmentManager().storeAttachment(att, data);とある。
|AttachmentManagerの574行目にm_provider.putAttachmentData( att, in )がある。これは、WikiAttachmentProviderというInterface Classに定義されているメソッド。実態はどこだ?org.apache.wiki.providersパッケージの中にいくつかある。
|この(InputStream)dataを圧縮後のファイルに置き換えるということか。
*一時的にファイルを保存したい。
|TOMCAT_HOMEの下にtempフォルダがあって、そこにアップロードするファイルが一時的に保存されている。プロパティのworkDirを使っているところを探そう。m_engine.getWorkDir()で取れるっぽい。そこに淡々と保存するか。で、そのファイルを開いて、InputStreamをつくるか。
*一時ファイルの削除
|もし一時ファイルに保存したとしたら、それを消すのはいつ?tempFile.deleteOnExit()
*画像ファイルからEXIF情報を削除するのはApache Commons Imaging[1]かな。
|in は InputStream、Outは、InputStreamってできる?一度Tempファイルで保存か。サンプルを見よう[4].
*画像のファイルサイズの圧縮ができるAPIはあるか?
|ImageIOってなんだろう[2]。いくつかサンプルが[3]。BufferredImageが便利。しかしImageオブジェクトをBufferredImageにキャストしようとしたらエラーがでた。同じ問題に当たった人も[5]
*なんとPNGってEXIF情報保存できないんだ。。。tiffにするか。いやApache Commons Imagingでは、TIFFはEXIFに対応していないように見える[6]。そうするとPNGにして、メタデータは、書誌情報として保存か。本当にそれでいい?ImageIOを使った方法[8]をちょっと調べたうえでやろう。JPEGに越したことはない。
*ファイル形式結論はJPEGで。
Apache Commons Imaging を使った場合。実は、JPEGの保存について、Imagingが対応していない[6]ためエラーorg.apache.commons.imaging.ImageWriteException: This image format (Jpeg-Custom) cannot be written.がでる。
{{{
Imaging.writeImage(buffered, tempImageFile, ImageFormats.JPEG, null);
}}}
ImageIOでやるとこうなる。画質が指定できないのが玉に傷だが、シンプルだ。
{{{
ImageIO.write(buffered, "jpeg", tempImageFile);
}}}
*なんか写真が180度回転して表示される。どうしたものか。EXIFにあるらしい、Orientationの情報をもとに回転させたほうがいいのかな。同じ問題に当たった人も[7]。EXIFのOrientationの値をゲットすると、3とかがでてきた。これは180度回転しているものらしい[9]。graphics2Dのrotateメソッドを使おう。
*ファイルサイズを選択するリストを最初Disableにしないと。(結局選択させないことに)
*Reziseをチェックしないのに動いちゃった。それはまずい。(結局全部リサイズすることに)
*ResizeをするとEXIFが消えるような気がする。当たり前なのだが。EXIF情報をコピーするとかできるのか?(結局全部消すことに)
*ファイルをいじるところをまとめたほうがいいと思う。(一回で済ませた)
**回転する(EXIF次第)
**Resizeする(必ずやる)
**EXIFを取得する(必ずやる)
**EXIF情報を付加する(やらないことにした)
**EXIF情報を削除する(回転などをやるとあえてコピーしないと消える。コピーの処理はやらないことにした)
*JPEG以外でアップロードされた場合どうするか。いまは、JPEGがPNGで保存。JPEGの時だけ動くようにしたい。(OK)
*JPEGでもアップロードできないファイルがある。Invalid marker found in entropy dataという.ImageReadExceptionがでる。まだこれで解決するかわからないけど、Apacheでも議論があって1.0-alpha2で解決されているという[10]。2020年5月7日時点では、Mavenレポジトリから呼べないのだけど。Githubのレポジトリから最新版をクローンして、コンパイルして1.0-alpha2のJARをゲットして、JSPWikiのWEB-INFのlibフォルダに入れて解決。
*ResizeしないとRotateされない。→もう面倒だから全部Resizeだ。
*ん?JPEGのファイルで、全体に赤とか、黄色とかがかかる現象が。試しにPNG形式で保存しようとしても、同じ結果だ。つまり、ImageIO.writeは悪くない。getScaledInstanceを飛ばしてみても結果は同じ。ここもあまり悪くなさそう。orientationValueが3か6以外の画像も同じ現象が起きたから、graphics2D.rotateも関係なさそうだ。graphics2D.drawImage()を飛ばしても結果は変わらない。Imaging.getBufferedImage(in)が怪しい。ここで得られたBufferedImageをそのままImageIO.writeしても結果は変わらない。ここは、Imaging.getBufferedImage(in)をImageIO.read(in)に代替して、解決
*iphoneだと90度回転がありうる。Orientation Valueとしては、6。この時、widthとheightが入れ替わることおよびその回転の中心座標に注意。
|orientation value|回転角度(°)|幅|高さ|回転の中心座標|
|1|0|width|height|回転しない|
|3|180 deg|width|height|(width/2, height/2)|
|6|90 deg|height|width|(height/2, height/2)|
!!!Referece
#[#1][http://commons.apache.org/proper/commons-imaging/]
#[#2][https://qiita.com/oohira/items/be99b3c8f025d04a5541]
#[#3]エンジニアの入り口, 2018.04.13,【入門者向け】Javaにおける画像の扱い方を分かり易く解説, [https://eng-entrance.com/java-image]
#[#4][http://commons.apache.org/proper/commons-imaging/sampleusage.html]
#[#5][https://stackoverflow.com/questions/13605248/java-converting-image-to-bufferedimage]
#[#6][http://commons.apache.org/proper/commons-imaging/formatsupport.html]
#[#7][http://mumumu.github.io/blog/2013/05/15/rotate-image-depending-on-exif-orientation-value/]
#[#8]@oohira, 2017年4月16日, JavaでJPEG画像の保存品質を変更する, [https://qiita.com/oohira/items/be99b3c8f025d04a5541]
#[#9]EXIF Tags, [https://exiftool.org/TagNames/EXIF.html]
#[#10]2019年6月9日, Invalid marker found in entropy data, [https://issues.apache.org/jira/browse/IMAGING-134]