Преобразование Bmp в jpg /png на C#
-
09-06-2019 - |
Вопрос
Есть ли какой-нибудь способ преобразовать bmp-изображение в jpg / png без потери качества в C #?Используя класс Image, мы можем преобразовать bmp в jpg, но качество выходного изображения очень низкое.Можем ли мы добиться такого же высокого качества, как изображение, преобразованное в jpg с помощью photoshop с высочайшим качеством?
Решение
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;
}
}
Предоставленные BitmapExtensions от jestro великолепны, я использовал их.Однако хотелось бы показать исправленную версию - работает для родительского класса 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 по своей природе является форматом с потерями.Таким образом, в thoery даже при самых высоких настройках у вас будет некоторая потеря информации, но это во многом зависит от изображения.Но 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 ... возможно, качество улучшилось в последующих выпусках фреймворка.