Java で ImageIO を使用して jpg画像 を保存すると品質劣化する問題への対応

三国志大戦の個人的な開発でTwitterにある画像をJavaのプログラム処理でローカルPCへ保存していた。
保存した画像を見てみると、明らかに画質の劣化が見受けられたので色々と調べてみました。

画質劣化はパターンマッチングにおいて致命的になりそうなので、妥協できない点です。

結論から書くと、ImageIOを使用せずにファイルとして取り扱えとなります。

以下、ImageIOを使用してTwitterの画像(mediaUrl)をローカルPCに保存(outputPath)している。

ImageIO.write(ImageIO.read(mediaUrl), "jpg", new File(outputPath));

ブラウザで保存した画像とImageIOを使用して保存した画像をWinMergeで比較してみる。
WinMergeは、いつから画像比較もできるようになったんだ。
WinMergeの進化が止まらない。
f:id:kameya_takefumi:20171116151524j:plain

差異がある部分が黄色になっている。
やっぱ画質劣化してるやん、詐欺やん。

調べてみると、画像保存時の品質設定がMAXではないらしい。

以下、品質設定MAXで行う処理。

try (FileImageOutputStream output = new FileImageOutputStream(new File(outputPath))) {

    BufferedImage readImage = ImageIO.read(mediaUrl);

    ImageWriter writeImage = ImageIO.getImageWritersByFormatName("jpeg").next();
    ImageWriteParam writeParam = writeImage.getDefaultWriteParam();
    writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    writeParam.setCompressionQuality(1.0f);
    writeImage.setOutput(output);
    writeImage.write(null, new IIOImage(readImage, null, null), writeParam);
    writeImage.dispose();
}

その結果。
f:id:kameya_takefumi:20171116151638j:plain

たいして変わってねぇ。
むしろ差異が増えている?
そもそもJpg画像として保存する事が自体がダメな気がしてきました。

以下、ファイルとして保存する処理。

try (ReadableByteChannel rbc = Channels.newChannel(mediaUrl.openStream());
        FileOutputStream fos = new FileOutputStream(outputPath)) {
    fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}

その結果。
f:id:kameya_takefumi:20171116151746j:plain

いけた。
Jpg画像を読み込んでJpg画像を出力すると品質劣化しますね。
Jpg自体、画像を圧縮する技術なので、圧縮処理されたものを、さらに圧縮処理する事になっているのか。
劣化するのは当たり前っちゃ当たり前ですね。

考えればわかりそうな事ですが、パッと思いつかなかったなぁ。
画像といえど、そのまま保存するならファイルとして扱うのがいいですね。
今更ながらの学び、でも大事。

中間管理録トネガワ(6)

中間管理録トネガワ(6) (ヤングマガジンコミックス)

中間管理録トネガワ(6) (ヤングマガジンコミックス)

面白い。
いやぁ凄い。

まさか海老谷がこんな形で再登場するとは思ってもみなかった。
海老谷の愛すべきバカっぷりは良いねぇ。

女性黒服西口のアドバイスがある話が一番好きかな。
的を得てて笑うし、最後、「兵藤会長が可哀想」って兵藤会長に共感してるのがツボった。
兵藤会長も無視するっていう幼さを感じる行動が良い。
制裁を加えない。
罰を与えない罰。
悪魔的だ!

まさやんも再登場してて良いねぇ。
まさやんの犬化が止まらない。
黒崎が怖すぎる。
初対面なのにまさやんに対しての教育が厳しすぎる。
黒崎の部下にはなりたくないねぇ。

kameyatakefumi.hatenablog.com

アカギ 35

アカギ 35 (近代麻雀コミックス)

アカギ 35 (近代麻雀コミックス)

長かった。
ギャグ調になって終わってしまった。

最初の 狂気の沙汰ほど面白い みたいな感じじゃないね。

作者は鷲巣の事が好きになりすぎじゃないかな。
部下の鷲巣信者みたいなヤツの語りとか面白いんだけど、鷲巣のスピンオフ漫画でやって欲しいなぁ。
あくまでもアカギが主人公なので、淡々とやって欲しかった。
スピンオフのノリに影響されるというか、張り合うのは違うと思う。

鷲巣編はこれで終わりだけど、漫画としては続くっぽいですね。
アカギにとっての最強の相手だっただけに続きはどうするんでしょ。

広告を非表示にする

僕のヒーローアカデミア 16

なかなかええんちゃうん。
ちょっと冗長な所はあったけど。

インターン生をカチコミ要員としてヤクザの家に突っ込ますのは、どうなん?って思います。
プロから見たら足手まといじゃないですかね。
生徒が死ぬような場所に行くようになったので、なんか、社会問題の解決に子どもを利用している感じがします。

ヒーローって消耗品なのかなって思うなぁ。

切島 と ファット の戦いは熱いですね。
敵キャラも個性があって好き。
戦闘狂は、切島を助けてくれるあたり無茶苦茶で、なぜ切島が気に入ったのかもよくわからないですが、まぁ細かいことはいいか。

サンイーター も悪くはないんですが、子どもに敵3人相手の判断はないよ。
今回、切島 も サンイーター も過去話を挟んでの勝利なので、ストーリーの流れが同じで冗長なんですよね。
過去、自信がない話しとかデクでやり尽くしているので、さらっと流していい気がします。

あと敵で個性ブーストする薬を使っているの一人だけなのか?
悪役なんだし、みんなガンガンにドーピングしていこうよ。

タイトルに アカデミア が入っているせいか主人公は「学生」みたいな縛りがあるせいで、話を広げるうえでの制約になってますね。

kameyatakefumi.hatenablog.com

マギ(36)

急な展開やな。

シンドバットの心変わりは凄い。
本当に頭が良いな。

ルフを書き換えたせいで凄い苦労する事になっていますね。

ルフに還す天使みたいヤツの造形が邪悪っぽくて、パッと見て神聖化する気にはなれないなぁ。
人々は喜んで近寄っていってるけど普通はなんだあれってなりそうですね。

ルフに還す天使ってモブキャラなので、その相手に苦労している主人公チームに違和感を覚えますね。

アリババが王の器に覚醒しましたが辛い状況が続きますね。
対話なく宣戦布告してくるあたり展開が急です。

世界を敵にまわしても意志を貫くってのは辛い事ですね。

展開として、別世界との対話をどう描くのか気になっていましたが、ダビデが出てきて、ちょっと残念かな。
次巻で完結みたいですね。
楽しみです。

kameyatakefumi.hatenablog.com

広告を非表示にする