在不损失任何质量的情况下调整图像大小[关闭]

Posted

技术标签:

【中文标题】在不损失任何质量的情况下调整图像大小[关闭]【英文标题】:Resizing an Image without losing any quality [closed] 【发布时间】:2010-09-10 09:45:48 【问题描述】:

如何在不影响图像质量的情况下调整图像大小?

【问题讨论】:

你能告诉我们更多细节吗?你的图片有多大,你需要多大? nathanaeljones.com/163/20-image-resizing-pitfalls imageresizing.net - 该库生成您可以使用 .NET 获得的最高质量图像 【参考方案1】:

正如rcar 所说,你不能不损失一些质量,你可以在 c# 中做的最好的事情是:

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));

【讨论】:

我可能会补充一点(如果可能的话),用户应该从一个位图图像开始,也就是说,它是所需大小的两倍,然后按比例缩小。生成的图像应该非常平滑。 gr.SmoothingMode = SmoothingMode.HighQuality 是更好的代码。目前,HighQuality 和 AntiAlias 是同一种东西,但也许未来微软会发明一些新东西。 HighQuality 应该始终是最好的别名。 Method 'System.Drawing.Image.Save(string filename, ImageFormat format)' 保存质量为 75 的 JPG。图像模糊,客户无法接受。解决质量问题的方法是改用 Save(string filename, ImageCodecInfo encoder, EncoderParameters encoderParams) 并指定更接近 100 的质量值。 这有时会在图像的边界上留下伪影...... 我在使用它的边界上有文物。有什么建议吗?【参考方案2】:

除非您正在制作矢量图形,否则无法在不损失一些图像质量的情况下调整图像大小。

【讨论】:

除非你扩展它... 您可以在不丢失任何信息的情况下对其进行扩展,但是您可以使用不同类型的过滤器来提供不同的结果 - 零阶保持、低通等。 可以确认,我戏剧性地说“增强!”到我的电脑,它没有工作。【参考方案3】:
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;

来自here

【讨论】:

这可行,但返回的质量与 Kris Erickso 的答案相同。很高兴看到使用的尺寸...【参考方案4】:

我相信您要做的是“调整大小/重新采样”您的图像。这是一个很好的网站,提供说明并提供实用程序类(我也碰巧使用):

http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx

【讨论】:

【参考方案5】:

除非您调整大小,否则您无法对光栅图形执行此操作。

您可以通过良好的过滤和平滑来调整大小而不会丢失任何显着质量。

您还可以更改图像的 DPI 元数据(假设它有一些),这将保持完全相同的像素数,但会改变图像编辑器在“真实世界”测量中对其的看法。

只是为了涵盖所有基础,如果您真的只是指图像的文件大小而不是实际图像尺寸,我建议您查看图像数据的无损编码。我对此的建议是将图像重新保存为 .png 文件(我倾向于使用画图作为 Windows 中图像的免费转码器。在画图中加载图像,另存为新格式)

【讨论】:

【参考方案6】:

您无法在不损失某些质量的情况下调整图像大小,这仅仅是因为您减少了像素数。

不要减小客户端的大小,因为浏览器不能很好地调整图像大小。

您可以做的是在渲染之前或在用户上传之前以编程方式更改大小。

这里有一篇文章解释了在 c# 中执行此操作的一种方法: http://www.codeproject.com/KB/GDI-plus/imageresize.aspx

【讨论】:

“浏览器在调整图像大小方面做得不好” - 这在 08 年可能是正确的,但幸运的是,我们现在在这个领域领先几英里(很大程度上是由于旧的IE 版本逐渐消失)。【参考方案7】:

看看你是否喜欢image resizing quality of this open source ASP.NET module. 有一个现场演示,所以你可以自己玩弄。它产生的结果(对我而言)无法与 Photoshop 输出区分开来。它也有类似的文件大小 - MS 在他们的 JPEG 编码器上做得很好。

【讨论】:

嗯,JPEG 是一种相对简单的格式。在质量/文件大小方面,您无法超越参考实现,因为最终它只是具有通用压缩的 DCT 系数。【参考方案8】:

在这里你也可以找到在这个类中添加水印代码:

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>();
        

    

【讨论】:

【参考方案9】:

那里有一些东西,上下文感知调整大小,不知道你是否能够使用它,但它值得一看,这是肯定的

一个不错的视频演示(放大出现在中间) http://www.youtube.com/watch?v=vIFCV2spKtg

这里可能有一些代码。 http://www.semanticmetadata.net/2007/08/30/content-aware-image-resizing-gpl-implementation/

那是不是有点矫枉过正?也许有一些简单的过滤器可以应用于放大的图像以稍微模糊像素,您可以研究一下。

【讨论】:

我怀疑这与原始问题无关,但我确实喜欢这种技术。【参考方案10】:

您是放大还是缩小?是小百分比还是更大的因素,例如 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

【讨论】:

【参考方案11】:

这是一个forum thread,它提供了一个 C# 图像大小调整代码示例。您可以使用 GD library 绑定器之一在 C# 中进行重新采样。

【讨论】:

以上是关于在不损失任何质量的情况下调整图像大小[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

python如何在不损失质量的情况下调整(缩小)图像的大小

如何在不损失图像质量的情况下调整图像大小以适合小型 HTML5 画布? [复制]

是否可以在不损失质量的情况下调整 UIImage 的大小?

在 python 中放大 SVG 图像而不损失其质量

如何使用 PIL 减小图像文件大小

目标 C:如何在不损失边缘质量的情况下从 JPG 图像中去除白色背景