none
C#(4.5)で、Pngファイルを保存する際の品質 RRS feed

  • 質問

  • c#でPngファイルの保存をしようとしていますが、妙に巨大なファイルが出来て困っています

    Bitmap src = new Bitmap(textBox1.Text);                        //ファイル取得(JPG)
    EncoderParameter encParam = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 24);    //24ビットを指定
    EncoderParameter encParam2 = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression,(long) EncoderValue.CompressionCCITT4);    //圧縮方法を指定(効果無し)
    EncoderParameters encParams = new EncoderParameters(2);        //パラメーターリスト
    encParams.Param[0] = encParam;                                //24ビットに指定したパラメーターを渡す
    encParams.Param[1] = encParam2;                                //圧縮方法を指定したパラメーターを渡す
    //src.Save(textBox2.Text, pngEncoder, encParams);                //PNGに変換
    src.Save(textBox2.Text, ImageFormat.Png);                //PNGに変換

    という単純なプログラムです
    どうも、ColorDepthもCompressionも無視されているようで(Compressionはtiffでしか効かないのですが実験でちょっと試してみました)
    常に24ビットのPngファイルが作成されます(ColorDepthを32にしても一緒)

    また、パラメーターを指定せずに単純にImageFormat.Pngとしても、同じファイルが出来上がります(何をやっても24ビット)

    ・・・・が、出来れば24ビットと32ビットのPngファイルを使い分けしたいです

    また、同じファイルを他のアプリで保存した場合(OSに付属のペイント)は
    常に32ビットで保存されるのですがサイズが10M程度なのですが
    上記のコードを使用すると24ビットなのに14Mというサイズになってしまいます(サイズ変換などは行っていません)

    なので、せめてもうちょっと小さいサイズで保存したいです

    ・24ビットと32ビットのPngファイルを使い分け
    ・圧縮アルゴリズムの選択があるのであればその使い分け

    の方法を教えてください

    2015年7月21日 5:31

回答

  • 32bitで保存する場合、保存対象のBitmapオブジェクトそのものを32bitで作成する必要があります。簡単には、Cloneメソッドを使用できます。なお、pngで保存する場合、EncoderParametersはまるっと無視されます。

    圧縮レベルは確か指定できる余地はなかったかと思います。

    • 回答としてマーク いちろう 2015年7月22日 5:54
    2015年7月21日 5:43
  • 24bit / 32bitはHongliangさんの指摘されている通り、Bitmap.PixelFormatプロパティで決まります。

    圧縮に関してですが、PNGは画像をzlib圧縮するため本来であれば圧縮レベル1~9が指定できますがそのようになっていません。実はPNGは画像を圧縮する前にピクセルデータを前処理します。そのパラメーター指定は複雑かつバリエーションがあるため指定しようがない状況で、それを踏まえて.NET Framework(正確には内部で使用しているGDI+)のPNGエンコーダーは圧縮レベルを一切受け付けなくなっています。

    必要であればOptiPNGなどの外部ツールを使いましょう。
    # ちょうど今サイトが死んでますが…(--

    • 回答としてマーク いちろう 2015年7月22日 5:54
    2015年7月21日 6:21

すべての返信

  • 32bitで保存する場合、保存対象のBitmapオブジェクトそのものを32bitで作成する必要があります。簡単には、Cloneメソッドを使用できます。なお、pngで保存する場合、EncoderParametersはまるっと無視されます。

    圧縮レベルは確か指定できる余地はなかったかと思います。

    • 回答としてマーク いちろう 2015年7月22日 5:54
    2015年7月21日 5:43
  • 24bit / 32bitはHongliangさんの指摘されている通り、Bitmap.PixelFormatプロパティで決まります。

    圧縮に関してですが、PNGは画像をzlib圧縮するため本来であれば圧縮レベル1~9が指定できますがそのようになっていません。実はPNGは画像を圧縮する前にピクセルデータを前処理します。そのパラメーター指定は複雑かつバリエーションがあるため指定しようがない状況で、それを踏まえて.NET Framework(正確には内部で使用しているGDI+)のPNGエンコーダーは圧縮レベルを一切受け付けなくなっています。

    必要であればOptiPNGなどの外部ツールを使いましょう。
    # ちょうど今サイトが死んでますが…(--

    • 回答としてマーク いちろう 2015年7月22日 5:54
    2015年7月21日 6:21
  • お二人ともありがとうございます。
    .NetFrameworkのPNGはパラメータ調整できないですか・・・

    OptiPNGにしろ何にしろライブラリ等の使用を検討してみます

    2015年7月22日 5:55