调整图像大小而不会丢失任何质量

时间:2008-09-17 21:16:09

标签: c# image image-scaling

我需要调整图像大小,但图像质量不会受此影响。

11 个答案:

答案 0 :(得分:210)

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

答案 1 :(得分:32)

除非您正在使用矢量图形,否则无法在不丢失图像质量的情况下调整图像大小。

答案 2 :(得分:23)

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:3)

您不能在不损失某些质量的情况下调整图像大小,因为您正在减少像素数。

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

您可以做的是在呈现之前以编程方式更改大小,或者在用户上传大小时。

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

答案 5 :(得分:3)

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

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

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

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

答案 6 :(得分:2)

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

答案 7 :(得分:1)

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

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

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

那有点矫枉过正吗?也许有一些简单的滤镜可以应用于放大的图像以稍微模糊像素,你可以看一下。

答案 8 :(得分:1)

你是在大一点还是更小?通过一小部分或更大的因素,如2x,3x?你的申请质量是什么意思?什么类型的图像 - 照片,硬边线条图或什么?编写自己的低级像素磨削代码或尝试使用现有库(.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

答案 9 :(得分: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>();
        }

    }

答案 10 :(得分:0)

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