如何在不影响图像质量的情况下调整图像大小?
正如rcar所说,您不能不失去一些品质,而在C#中可以做到的最好是:
1 2 3 4 5 6 7 8
| Bitmap newImage = new Bitmap(newWidth, newHeight);
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.HighQuality;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
} |
除非您要进行矢量图形处理,否则就无法在不损失某些图像质量的情况下调整图像大小。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
} |
从这里
我相信您要执行的操作是"调整大小/重新采样"图像。这是一个提供指导并提供实用程序类的好站点(我也碰巧使用过):
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
除非调整大小,否则无法使用光栅图形执行此操作。
使用良好的过滤和平滑功能,您可以在不损失任何明显质量的情况下调整大小。
您还可以更改图像的DPI元数据(假设它有一些),这将保持完全相同的像素数,但会更改图像编辑器在"实际"测量中的想法。
只是为了覆盖所有基础,如果您实际上仅表示图像的文件大小而不是实际的图像大小,建议您查看图像数据的无损编码。我的建议是将图像重新保存为.webp文件(我倾向于使用paint作为Windows中图像的免费转码器。将图像加载到paint中,另??存为新格式)
您仅在减少像素数的情况下就无法调整图像的大小而不会降低质量。
不要减小客户端的大小,因为浏览器无法很好地调整图像的大小。
您可以做的是在渲染或用户上载之前以编程方式更改大小。
这是一篇文章,解释了在c#中执行此操作的一种方法:
http://www.codeproject.com/KB/GDI-plus/imageresize.aspx
查看您是否喜欢此开源ASP.NET模块的图像调整大小质量。有一个现场演示,因此您可以自己弄弄它。它产生的结果(对我而言)是无法与Photoshop输出区分开的。它还具有相似的文件大小-MS在其JPEG编码器上做得很好。
在这里,您还可以在此类中添加水印代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| public class ImageProcessor
{
public Bitmap Resize(Bitmap image, int newWidth, int newHeight, string message)
{
try
{
Bitmap newImage = new Bitmap(newWidth, Calculations(image.Width, image.Height, newWidth));
using (Graphics gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(image, new Rectangle(0, 0, newImage.Width, newImage.Height));
var myBrush = new SolidBrush(Color.FromArgb(70, 205, 205, 205));
double diagonal = Math.Sqrt(newImage.Width * newImage.Width + newImage.Height * newImage.Height);
Rectangle containerBox = new Rectangle();
containerBox.X = (int)(diagonal / 10);
float messageLength = (float)(diagonal / message.Length * 1);
containerBox.Y = -(int)(messageLength / 1.6);
Font stringFont = new Font("verdana", messageLength);
StringFormat sf = new StringFormat();
float slope = (float)(Math.Atan2(newImage.Height, newImage.Width) * 180 / Math.PI);
gr.RotateTransform(slope);
gr.DrawString(message, stringFont, myBrush, containerBox, sf);
return newImage;
}
}
catch (Exception exc)
{
throw exc;
}
}
public int Calculations(decimal w1, decimal h1, int newWidth)
{
decimal height = 0;
decimal ratio = 0;
if (newWidth < w1)
{
ratio = w1 / newWidth;
height = h1 / ratio;
return height.To<int>();
}
if (w1 < newWidth)
{
ratio = newWidth / w1;
height = h1 * ratio;
return height.To<int>();
}
return height.To<int>();
}
} |
您要调整大小还是缩小?是较小的百分比还是较大的系数(例如2倍,3倍)?您的应用程序质量是什么意思?什么样的图像-照片,硬边线图或什么?编写自己的低级像素研磨代码还是尝试使用现有库(.net或其他任何形式)来尽可能地做到这一点?
有关此主题的知识很多。关键概念是插值。
浏览建议:
* http://www.all-in-one.ee/~dersch/interpolator/interpolator.html
* http://www.cambridgeincolour.com/tutorials/image-interpolation.htm
*适用于C#:https://secure.codeproject.com/KB/GDI-plus/imageprocessing4.aspx?display = PrintAll&fid = 3657&df = 90&mpp = 25&noise = 3&sort = Position&view = Quick&fr = 26&select = 629945
*这是特定于Java的,但可能具有教育意义-http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
有一些东西,可以根据上下文调整大小,不知道是否可以使用它,但是值得一看,这是肯定的
一个不错的视频演示(放大出现在中间)
这里可能有一些代码。
Content Aware Image Resizing: GPL Implementation
那是过度杀伤力吗?也许有一些简单的滤镜可以应用于放大的图像,使像素稍微有些模糊,您可以查看一下。
这是一个提供C#图片大小调整代码示例的论坛线程。您可以使用GD库联编程序之一在C#中进行重采样。