DOBON.NET DOBON.NETプログラミング掲示板過去ログ

JPEG画像を、縦横の大きさを変えず、指定容量以下に変換する

環境/言語:[Microsoft Visual C# 2010 Express]
分類:[その他]

現在、C#で、JPEG画像ファイルの縦横の長さを変えず、ファイルサイズ(容量)を40kB以下に変換して別フォルダに保管するプログラムを作成しています。

その際、下記URLを参考にして、品質レベル=100から画像を生成し始め、
保存した画像の容量が40kBを超えていたら、品質レベルを下げ、
画像容量が40kB以下になるか、最小品質レベルになったら終了する、という
プログラムを作成しました。

http://dobon.net/vb/dotnet/graphics/encoderparameters.html

しかし、この方法で画像を保存したところ、品質レベルを最小にしても
画像容量が40kB以下にならないケースが発生し、
どうすれば40kB以下にすることができるか分からず悩んでいます。

「縮小専用。」という専用のソフトを使うと、
確実に40kB以下にすることができるので、プログラムによって
冒頭に記載した処理をすることができる方法が何かしらあると考えていますが、
「このようにすればできる」という方法が見つからず困っています。

冒頭に記載した処理を実現させる適切な方法、あるいはヒントとなる検索キーワードがありましたら、教えていただけるとありがたいです。

以上、よろしくお願いします。
http://i-section.net/software/shukusen/
このツールで良いんですかね。
試しに使ってみたところ、量子化率1でも40kBにならないような画像を40kB以下に圧縮するように指示すると、なんか圧縮を放棄する(いつまで経っても終わらない、CPUも使わない)ような動作を示すのですが。もうしばらく待てば終わったのかしら。
このツールで量子化率1に指定して出力した画像と、Encoder.Quality=1で出力した画像とで、出力サイズおよび画像の見た目は大体一致しますし。
Quality=1でぎりぎり40kBになるかならないかという画像相手の話でしょうか?
■No32606に返信(Hongliangさんの記事)
> http://i-section.net/software/shukusen/
> このツールで良いんですかね。
> 試しに使ってみたところ、量子化率1でも40kBにならないような画像を40kB以下に圧縮するように指示すると、なんか圧縮を放棄する(いつまで経っても終わらない、CPUも使わない)ような動作を示すのですが。もうしばらく待てば終わったのかしら。
> このツールで量子化率1に指定して出力した画像と、Encoder.Quality=1で出力した画像とで、出力サイズおよび画像の見た目は大体一致しますし。
> Quality=1でぎりぎり40kBになるかならないかという画像相手の話でしょうか?

Hongliangさん

昨日、掲示板に投稿する前に「縮小専用。」で量子化率1でも40kBにならないような画像を変換しましたが、40kB以内にすることができました。
「指定の範囲内にピクセルサイズを収める」で元ファイルと同じピクセルサイズに、オプションで、ファイルサイズを指定にチェックを入れ、40kBに設定して変換すればOKでした。この設定でもう一度試していただきたいのですが。

[補足]
縦横サイズを変えずに指定容量以下にする方法について、インターネット上で探してみましたが、フリーソフトではなく、ソースコード(言語はC#以外でも可)で実現できる方法が見つからず困っています。
良い解決策が見つかった方がいましたら、アドバイスをお願いします。

以上
添付ファイル: testimg.jpg (83 KB)
■No32607に返信(youkoさんの記事)
> 昨日、掲示板に投稿する前に「縮小専用。」で量子化率1でも40kBにならないような画像を変換しましたが、40kB以内にすることができました。

添付画像のことでしょうか。
だとしたら、原因はメタデータでは無いですかね。いわゆる EXIF 。

添付画像をファイルに保存して右クリックしてみると、
プロパティ画面の詳細タブにて、下記のタグ情報が列挙されます。
これらを削除してみては如何でしょうか?

  プログラム名 := "K-m Ver 1.00"
  カメラの製造元 := "PENTAX"
  カメラのモデル := "PENTAX K-m"
  絞り値 := "f/5.6"
  露出時間 := 1/90 秒"
  ISO 速度 := "ISO-200"
  露出補正 := "0 ステップ"
  焦点距離 := "48 mm"
  測光モード := "パターン"
  フラッシュ モード := "フラッシュなし (強制)"
  35mm 焦点距離 := "72"
  コントラスト := "標準"
  露出プログラム := "深度優先"
  彩度 := "標準"
  鮮明度 := "標準"
  ホワイト バランス := "自動"
  EXIF バージョン := "0221"
サンプル画像を確認しましたが、これはExifタグのデータの容量がかなりの部分を占めていますね。
.NETのSystem.Drawingでは、ImageオブジェクトのPropertyItemsListプロパティなどからExifタグのデータを取得できます。
http://dobon.net/vb/dotnet/graphics/getexifinfo.html
https://code.google.com/p/exif-utils/source/browse/trunk/ExifUtils/ExifUtils/Exif/ExifTag.cs?spec=svn175&r=175

ファイルからNewしたBitmapをそのままSaveするのではなく、
New Bitmap(Integer, Integer, PixelFormat)で元画像と同じサイズの幅・高さ・24bppのBitmapを作成し、
この新しいBitmapからGraphics.FromImageで作ったGraphicsに、元画像をDrawImageして、
その上で新しいBitmapを保存するようにしてみてください。

// ExifタグはRemovePropertyItemで消せるはずなんだけど、
// そのままSaveすると、GDI+次第で消せたり消せなかったりと不安定……。
■No32608に返信(魔界の仮面弁士さんの記事)

> 添付画像をファイルに保存して右クリックしてみると、
> プロパティ画面の詳細タブにて、下記のタグ情報が列挙されます。
> これらを削除してみては如何でしょうか?

>   プログラム名 := "K-m Ver 1.00"
>   カメラの製造元 := "PENTAX"
>   カメラのモデル := "PENTAX K-m"
>   絞り値 := "f/5.6"
>   露出時間 := 1/90 秒"
>   ISO 速度 := "ISO-200"
>   露出補正 := "0 ステップ"
>   焦点距離 := "48 mm"
>   測光モード := "パターン"
>   フラッシュ モード := "フラッシュなし (強制)"
>   35mm 焦点距離 := "72"
>   コントラスト := "標準"
>   露出プログラム := "深度優先"
>   彩度 := "標準"
>   鮮明度 := "標準"
>   ホワイト バランス := "自動"
>   EXIF バージョン := "0221"

回答ありがとうございます。
添付ファイルは、品質レベル最小でも40kB以下に変換できなかった画像です。
変換できた画像と比較したところ、
EXIFに原因がある可能性が高いと
考えています。
この方法で、40kB以下に変換できるか確認してみます。
以上、よろしくお願いします。
皆さんのおかげで解決できました。

ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板