C# での Bmp から jpg/png への変換
-
09-06-2019 - |
質問
C#で品質を落とさずにbmp画像をjpg/pngに変換する方法はありますか?Image クラスを使用すると、bmp を jpg に変換できますが、出力画像の品質は非常に低くなります。最高品質の Photoshop を使用して jpg に変換した画像と同等の品質レベルを得ることができますか?
解決
var qualityEncoder = Encoder.Quality;
var quality = (long)<desired quality>;
var ratio = new EncoderParameter(qualityEncoder, quality );
var codecParams = new EncoderParameters(1);
codecParams.Param[0] = ratio;
var jpegCodecInfo = <one of the codec infos from ImageCodecInfo.GetImageEncoders() with mime type = "image/jpeg">;
bmp.Save(fileName, jpegCodecInfo, codecParams); // Save to JPG
他のヒント
public static class BitmapExtensions
{
public static void SaveJPG100(this Bitmap bmp, string filename)
{
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
bmp.Save(filename, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static void SaveJPG100(this Bitmap bmp, Stream stream)
{
EncoderParameters encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
bmp.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
}
jestro が提供する BitmapExtensions は素晴らしいので、使用しました。ただし、修正されたバージョンを示したいと思います。Image 親クラスで動作します。これは、私が思うように、より便利で、品質を提供する方法を提供します。
public static class ImageExtensions
{
public static void SaveJpeg(this Image img, string filePath, long quality)
{
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
img.Save(filePath, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
public static void SaveJpeg(this Image img, Stream stream, long quality)
{
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, quality);
img.Save(stream, GetEncoder(ImageFormat.Jpeg), encoderParameters);
}
static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
return codecs.Single(codec => codec.FormatID == format.Guid);
}
}
基本的に、jpg は (私の知る限りでは) 最高の品質設定であっても常に損失があるため、同じ品質を維持することはできません。
ビット精度の品質が本当に重要な場合は、可逆モードがいくつかある png の使用を検討してください。
JPEG は本質的に非可逆形式であると言いたいだけです。したがって、理論的には、最高の設定でもいくらかの情報の損失が発生しますが、それは画像に大きく依存します。しかし、png は損失がありません。
あなたが試すことができます:
Bitmap.InterpolationMode = InterpolationMode.HighQualityBicubic;
そして
Bitmap.CompositingQuality = CompositingQuality.HighQuality;
これにより、品質はかなり高く保たれますが、可能な限り最高ではありません。
私は経費報告書アプリに取り組んでいますが、ビットマップ オブジェクトから保存するときの JPG (および PNG) のデフォルトの品質設定に非常に満足しています。
https://msdn.microsoft.com/en-us/library/9t4syfhh%28v=vs.110%29.aspx
Bitmap finalBitmap = ....; //from disk or whatever
finalBitmap.Save(xpsFileName + ".final.jpg", ImageFormat.Jpeg);
finalBitmap.Save(xpsFileName + ".final.png", ImageFormat.Png);
私は .NET 4.6 を使用しています...おそらく、その後のフレームワーク リリースで品質が向上しました。