【问题标题】:Resize with minimal loss of quality以最小的质量损失调整大小
【发布时间】:2015-03-04 06:11:38
【问题描述】:

我需要调整图像大小,但图像质量不会受此影响,图像会从 10x10 到 1000x1000,它会有一些严重的拥塞和一些空白时间 它必须同时放大和缩小“可能会损失一些图像质量”。可以,但至少必须是光栅图形的所有内容 请不要使用库或其他外部二进制文件

【问题讨论】:

  • 你做错了。使用矢量图形格式,这不是问题。
  • @oidfrosty 如果没有库或其他外部二进制文件,您想要的东西(尤其是在这种规模和任何半有用质量的情况下)可能无法实现。图像增强是一个庞大的研究领域。
  • 好吧,因为这是我的第一份工作之一,我很想尽可能多地学习,所以我想至少保持“外部工作”@Stefan Kendall 我真的不知道“光栅图形的一切”是如何让你认为我实际上可以用矢量来做的吗?

标签: c# image


【解决方案1】:

这里有一个链接告诉你如何调整图像大小:

http://snippets.dzone.com/posts/show/4336

【讨论】:

    【解决方案2】:

    每当您调整图像大小时,都会有一些质量损失 - 没有办法解决这个问题,但您可以通过在图形上下文中使用最高质量选项来帮助将其最小化。

    这是我使用普通 GDI+ 函数时使用的:

    public static Bitmap ResizeImage(Bitmap bmp, int width, int height, 
                                     InterpolationMode mode = InterpolationMode.HighQualityBicubic)                                         
    {
        Bitmap bmpOut = null;
    
        try
        {                                
            decimal ratio;
            int newWidth = 0;
            int newHeight = 0;
    
            // If the image is smaller than a thumbnail just return original size
            if (bmp.Width < width && bmp.Height < height)
            {
                newWidth = bmp.Width;
                newHeight = bmp.Height;
            }
            else
            {
                if (bmp.Width == bmp.Height)
                {
                    if (height > width)
                    {
                        newHeight = height;
                        newWidth = height;
                    }
                    else
                    {
                        newHeight = width;
                        newWidth = width;                         
                    }
                }
                else if (bmp.Width >= bmp.Height)
                {
                    ratio = (decimal) width/bmp.Width;
                    newWidth = width;
                    decimal lnTemp = bmp.Height*ratio;
                    newHeight = (int) lnTemp;
                }
                else
                {
                    ratio = (decimal) height/bmp.Height;
                    newHeight = height;
                    decimal lnTemp = bmp.Width*ratio;
                    newWidth = (int) lnTemp;
                }
            }
    
            //bmpOut = new Bitmap(bmp, new Size( newWidth, newHeight));                     
            bmpOut = new Bitmap(newWidth, newHeight);                
            bmpOut.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
    
            Graphics g = Graphics.FromImage(bmpOut);
            g.InterpolationMode = mode;
    
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    
            g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
            g.DrawImage(bmp, 0, 0, newWidth, newHeight);                
        }
        catch
        {
            return null;
        }
    
        return bmpOut;
    }
    

    这会将图像的大小调整为宽度或高度中的最大值 - 您可以更改该算法以满足调整大小的需要。

    如果你想处理文件,你可以添加另一个包装上面代码的助手:

    public static bool ResizeImage(string filename, string outputFilename, 
                                    int width, int height, 
                                    InterpolationMode mode = InterpolationMode.HighQualityBicubic)
    {
    
        using (var bmpOut = ResizeImage(filename, width, height, mode) )
        {
            var imageFormat = GetImageFormatFromFilename(filename);
            if (imageFormat == ImageFormat.Emf)
                imageFormat = bmpOut.RawFormat; 
    
            bmpOut.Save(outputFilename, imageFormat);
        }
    
        return true;
    }
    

    GDI+ 通常不是高质量图像处理的最佳解决方案 - 它很不错,但如果您需要 Web 应用程序中的最高质量、更好的性能和线程安全,则需要考虑其他选项。

    Bertrand LeRoy 前段时间发表了一篇关于图像调整大小的精彩文章,其中提供了一些使用核心 .NET 框架的替代方案。 http://weblogs.asp.net/bleroy/state-of-net-image-resizing-how-does-imageresizer-do

    【讨论】:

      【解决方案3】:

      您需要让您的图片具有可扩展性。我建议使用 XML 格式来存储您的图像,因为 XML 具有很强的可扩展性。例如:

      <Image Width="640" Height="480">
        <Pixel X="0" Y="0">
          <Red>20</Red>
          <Green>80</Green>
          <Blue>0</Blue>
          <Alpha>255</Alpha>
        </Pixel>
        <Pixel X="1" Y="0">
          ...
      

      如果您担心内存问题,我敢打赌这会很好地压缩 :-)。

      【讨论】:

      • 这是……这是讽刺吗?如果是这样,太棒了!如果没有,也许你需要一个词库...... :-)
      • @oidfrosty -- 这当然不是一个完整的解决方案,但是如果您像这样存储图像,您可以通过使用 XSLT + XPath 来实现类似上述的技术,这将更具可读性& 比 C# 解决方案可扩展。事实上,大多数图像处理任务(如裁剪、调整大小、级别等)都可以简化为 XSLT。
      • @NickAldwin - 关于 XML,我不会开玩笑。
      猜你喜欢
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      相关资源
      最近更新 更多