C# 高质量图像缩放库
我想用C#缩放一幅图像,质量水平和Photoshop一样好。是否有任何C#图像处理库可用于执行此操作?当您使用GDI+绘制图像时,我认为它的缩放效果相当好。可以使用此选项创建缩放图像 如果要使用GDI+缩放图像,可以执行以下操作:C# 高质量图像缩放库,c#,image,image-processing,image-manipulation,image-scaling,C#,Image,Image Processing,Image Manipulation,Image Scaling,我想用C#缩放一幅图像,质量水平和Photoshop一样好。是否有任何C#图像处理库可用于执行此操作?当您使用GDI+绘制图像时,我认为它的缩放效果相当好。可以使用此选项创建缩放图像 如果要使用GDI+缩放图像,可以执行以下操作: Bitmap original = ... Bitmap scaled = new Bitmap(new Size(original.Width * 4, original.Height * 4)); using (Graphics graphics = Graphi
Bitmap original = ...
Bitmap scaled = new Bitmap(new Size(original.Width * 4, original.Height * 4));
using (Graphics graphics = Graphics.FromImage(scaled)) {
graphics.DrawImage(original, new Rectangle(0, 0, scaled.Width, scaled.Height));
}
已测试的库(如和)可用于.NET
您也可以阅读双三次插值之类的内容,然后自己编写。尝试Graphics.InterpolationMode的不同值。GDI+中有几种典型的缩放算法。如果其中一个足以满足您的需要,您可以使用此方法,而不必依赖外部库。关于使用GDI+for.NET使用双三次插值来调整照片大小,有一个简单的方法
在另一个博客(我想是微软员工)上也有关于这个话题的文章,但我在任何地方都找不到链接(也许其他人可以找到它?CodeProject文章讨论并共享缩放图像的源代码:
// BiCubic is one technique available in PhotoShop
ResampleCommand resampler = new ResampleCommand(newSize, ResampleMethod.BiCubic);
AtalaImage newImage = resampler.Apply(oldImage).Image;
此外,dotImage还包括140个奇怪的图像处理命令,其中包括许多与PhotoShop中的过滤器类似的过滤器(如果您正在寻找这些过滤器的话)。这里有一个注释很好的图像处理帮助器类,您可以查看并使用它。我将其作为如何在C#中执行某些图像处理任务的示例e对采用System.Drawing.Image、宽度和高度作为参数的ResizeImage函数感兴趣
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
namespace DoctaJonez.Drawing.Imaging
{
/// <summary>
/// Provides various image untilities, such as high quality resizing and the ability to save a JPEG.
/// </summary>
public static class ImageUtilities
{
/// <summary>
/// A quick lookup for getting image encoders
/// </summary>
private static Dictionary<string, ImageCodecInfo> encoders = null;
/// <summary>
/// A lock to prevent concurrency issues loading the encoders.
/// </summary>
private static object encodersLock = new object();
/// <summary>
/// A quick lookup for getting image encoders
/// </summary>
public static Dictionary<string, ImageCodecInfo> Encoders
{
//get accessor that creates the dictionary on demand
get
{
//if the quick lookup isn't initialised, initialise it
if (encoders == null)
{
//protect against concurrency issues
lock (encodersLock)
{
//check again, we might not have been the first person to acquire the lock (see the double checked lock pattern)
if (encoders == null)
{
encoders = new Dictionary<string, ImageCodecInfo>();
//get all the codecs
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
{
//add each codec to the quick lookup
encoders.Add(codec.MimeType.ToLower(), codec);
}
}
}
}
//return the lookup
return encoders;
}
}
/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
{
//a holder for the result
Bitmap result = new Bitmap(width, height);
//set the resolutions the same to avoid cropping due to resolution differences
result.SetResolution(image.HorizontalResolution, image.VerticalResolution);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the image into the target bitmap
graphics.DrawImage(image, 0, 0, result.Width, result.Height);
}
//return the resulting bitmap
return result;
}
/// <summary>
/// Saves an image as a jpeg image, with the given quality
/// </summary>
/// <param name="path">Path to which the image would be saved.</param>
/// <param name="quality">An integer from 0 to 100, with 100 being the
/// highest quality</param>
/// <exception cref="ArgumentOutOfRangeException">
/// An invalid value was entered for image quality.
/// </exception>
public static void SaveJpeg(string path, Image image, int quality)
{
//ensure the quality is within the correct range
if ((quality < 0) || (quality > 100))
{
//create the error message
string error = string.Format("Jpeg image quality must be between 0 and 100, with 100 being the highest quality. A value of {0} was specified.", quality);
//throw a helpful exception
throw new ArgumentOutOfRangeException(error);
}
//create an encoder parameter for the image quality
EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
//get the jpeg codec
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
//create a collection of all parameters that we will pass to the encoder
EncoderParameters encoderParams = new EncoderParameters(1);
//set the quality parameter for the codec
encoderParams.Param[0] = qualityParam;
//save the image using the codec and the parameters
image.Save(path, jpegCodec, encoderParams);
}
/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
public static ImageCodecInfo GetEncoderInfo(string mimeType)
{
//do a case insensitive search for the mime type
string lookupKey = mimeType.ToLower();
//the codec to return, default to null
ImageCodecInfo foundCodec = null;
//if we have the encoder, get it to return
if (Encoders.ContainsKey(lookupKey))
{
//pull the codec from the lookup
foundCodec = Encoders[lookupKey];
}
return foundCodec;
}
}
}
注
请记住,图像是一次性的,因此您需要将调整大小的结果指定给using声明(或者您可以使用try FILLING并确保在FILLING中调用dispose)这是我在Paint.NET的图像重采样代码中看到的一篇文章,作者是Paul Bourke。如果这是一篇低分辨率cgi,你可以试试看 这可能会有所帮助
public Image ResizeImage(Image source, RectangleF destinationBounds)
{
RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height);
RectangleF scaleBounds = new RectangleF();
Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height);
Graphics graph = Graphics.FromImage(destinationImage);
graph.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// Fill with background color
graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds);
float resizeRatio, sourceRatio;
float scaleWidth, scaleHeight;
sourceRatio = (float)source.Width / (float)source.Height;
if (sourceRatio >= 1.0f)
{
//landscape
resizeRatio = destinationBounds.Width / sourceBounds.Width;
scaleWidth = destinationBounds.Width;
scaleHeight = sourceBounds.Height * resizeRatio;
float trimValue = destinationBounds.Height - scaleHeight;
graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight);
}
else
{
//portrait
resizeRatio = destinationBounds.Height/sourceBounds.Height;
scaleWidth = sourceBounds.Width * resizeRatio;
scaleHeight = destinationBounds.Height;
float trimValue = destinationBounds.Width - scaleWidth;
graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height);
}
return destinationImage;
}
请注意插值模式。高质量双三次->这通常是性能和结果之间的良好折衷。使用此库:
阅读图书馆作者的这篇文章:你可以试试。它在放大时比双三次重采样产生更少的像素伪影,在缩小时也能产生非常好的效果。
源代码可以从网站上以c语言获得。尝试以下基本代码片段:
private static Bitmap ResizeBitmap(Bitmap srcbmp, int width, int height )
{
Bitmap newimage = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(newimage))
g.DrawImage(srcbmp, 0, 0, width, height);
return newimage;
}
我对琼斯医生的答案有一些改进 它适用于那些想按比例调整图像大小的人。它对我进行了测试,也适用于我 第一类的方法增加了:
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, Size size)
{
return ResizeImage(image, size.Width, size.Height);
}
public static Size GetProportionedSize(Image image, int maxWidth, int maxHeight, bool withProportion)
{
if (withProportion)
{
double sourceWidth = image.Width;
double sourceHeight = image.Height;
if (sourceWidth < maxWidth && sourceHeight < maxHeight)
{
maxWidth = (int)sourceWidth;
maxHeight = (int)sourceHeight;
}
else
{
double aspect = sourceHeight / sourceWidth;
if (sourceWidth < sourceHeight)
{
maxWidth = Convert.ToInt32(Math.Round((maxHeight / aspect), 0));
}
else
{
maxHeight = Convert.ToInt32(Math.Round((maxWidth * aspect), 0));
}
}
}
return new Size(maxWidth, maxHeight);
}
这是C语言,其他问题是C++,所以它不是复制品。库提供了最高质量和最高性能的图像大小调整。接受的答案是牺牲品,它会在每个图像周围产生1px宽的边界伪影。他是DrawImage调用的最后一个参数。@计算机语言学家——TileModeXY是一个打字错误吗?您已经在多个答案上复制粘贴了此评论,并在谷歌上搜索了确切的“TileModeXY”仅显示您的帖子。System.Drawing.Drawing2D.WrapMode的以下链接仅显示5个可能的值:平铺、平铺、平铺、平铺。是的,它应该是平铺,感谢您的更正!ImageCodeInfo jpegCodec=getEncoderInfo(“图像/jpeg”);-你在哪里定义了getEncoderInfo,因为我无法编译它应该是getEncoderInfo,而不是getEncoderInfo。我修复了输入错误,类现在可以编译了。+1这非常有效!在这段代码中,你需要纠正的一个问题是在将质量变量传递给编码器参数之前将其转换为一个长参数,否则你将得到一个无效的参数eter运行时异常。@Behzad,如果您注意的话,SaveJpeg函数接受一个名为quality的int参数。您需要调用该参数并为quality参数指定正确的值(它接受一个介于0和100之间的值)。经过长时间搜索后,此答案的大小部分(没有使用整个代码)用于qrcode大小调整而不丢失质量。正确的设置对于结果质量非常重要。具有此功能的SDK现在可免费用于常见照片格式(JPEG、PNG等)/Lou Franco:common format free版本可以在生产部署中免费使用吗?是的,DotImage Photo free可以免费部署。不确定代码是否已更改,但我不得不在
缩放的声明中省略新大小
:新位图(original.Width*4,original.Height*4)
1:文章不错。无法访问链接,但找到了另一个链接:我在原始帖子中更正了链接,因为托马斯的链接也被破坏了……如果这个答案解释了答案的相关部分,而不是依赖链接,那会更好。
public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, Size size)
{
return ResizeImage(image, size.Width, size.Height);
}
public static Size GetProportionedSize(Image image, int maxWidth, int maxHeight, bool withProportion)
{
if (withProportion)
{
double sourceWidth = image.Width;
double sourceHeight = image.Height;
if (sourceWidth < maxWidth && sourceHeight < maxHeight)
{
maxWidth = (int)sourceWidth;
maxHeight = (int)sourceHeight;
}
else
{
double aspect = sourceHeight / sourceWidth;
if (sourceWidth < sourceHeight)
{
maxWidth = Convert.ToInt32(Math.Round((maxHeight / aspect), 0));
}
else
{
maxHeight = Convert.ToInt32(Math.Round((maxWidth * aspect), 0));
}
}
}
return new Size(maxWidth, maxHeight);
}
using (var resized = ImageUtilities.ResizeImage(image, ImageUtilities.GetProportionedSize(image, 50, 100)))
{
ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90);
}