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


108

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


您能给我们更多细节吗?您的图片有多大,需要多少尺寸?
Mark Ransom


6
imageresizing.net-该库可生成您可以使用.NET获得的最高质量图像
Lilith River

Answers:


217

正如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));
}

2
我可能会补充一点(如果可能的话),用户应该从一个位图图像开始,例如,它是所需图像的两倍,然后按比例缩小。生成的图像应该非常平滑。
椒盐脆饼

2
gr.SmoothingMode = SmoothingMode.HighQuality是更好的代码。当前,HighQuality和AntiAlias是同一回事,但也许将来微软会发明一些新东西。高品质应该始终是最好的别名。
2012年

4
方法“ System.Drawing.Image.Save(字符串文件名,ImageFormat格式)”以质量75保存JPG。图像模糊,客户端不接受。什么固定的质量问题是使用保存(字符串文件名,ImageCodecInfo编码器,EncoderParameters encoderParams)来代替,并指定一个质量值接近100
里加

3
这有时会在图像的边界上留下伪像……
jjxtra 2014年

1
我在使用它的边界上有人工制品。有什么建议吗?
Gopichandar 2015年

32

除非您要进行矢量图形处理,否则就无法在不损失某些图像质量的情况下调整图像大小。


1
除非您进行扩展...
Blair Conrad

你可以展开它不会丢失任何信息,但也有不同的类型,你可以用它给出不同的结果过滤器-零阶保持,低通,等等
亚当罗森菲尔德

24
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;
}

这里


这是有效的,但返回的质量与Kris Erickso的回答相同。很高兴看到使用的大小…
萨姆·琼斯


3

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

您可以通过良好的过滤和平滑操作来调整大小,而不会损失任何明显的质量。

您还可以更改图像的DPI元数据(假设它有一些),以保持完全相同的像素数,但会更改图像编辑器在“实际”测量中的想法。

只是为了覆盖所有基础,如果您实际上仅表示图像的文件大小而不是实际的图像大小,那么建议您查看图像数据的无损编码。我的建议是将图像重新保存为.png文件(我倾向于使用paint作为Windows中图像的免费转码器。将图像加载到paint中,另​​存为新格式)


3

您仅在减少像素数的情况下就无法调整图像的大小而不会降低质量。

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

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

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


“浏览器不能很好地调整图像大小”-在08年可能是这样,但是幸运的是我们现在在这一领域遥遥领先(很大程度上是由于旧的IE版本逐渐消失)。
卡米洛·马丁

2

查看您是否喜欢此开源ASP.NET模块图像调整大小质量。有一个现场演示,因此您可以自己弄弄它。它产生的结果(对我而言)是无法与Photoshop输出区分开的。它还具有相似的文件大小-MS在其JPEG编码器上做得很好。


嗯,JPEG是一种相对简单的格式。在质量/文件大小方面,您可以做很多事情来击败参考实现,因为最后只是具有通用压缩的DCT系数。
卡米洛·马丁

1

有一些东西,可以根据上下文调整大小,不知道是否可以使用它,但是值得一看,这是肯定的

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

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

那是过度杀伤力吗?也许有一些简单的滤镜可以应用于放大的图像,使像素稍微有些模糊,您可以查看一下。


我怀疑这与原始问题无关,但我确实喜欢这种技术。
马特·克鲁克香克

1

您要调整大小还是缩小?是小的百分比还是更大的系数,例如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


1

在这里,您还可以在此类中添加水印代码:

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

    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.