【问题标题】:C# GDI+ Image Resize FunctionC# GDI+ 图像调整大小功能
【发布时间】:2011-02-21 03:38:52
【问题描述】:

所以我的逻辑有缺陷,我需要一种更好更正确的方法来调整我的 c# 应用程序中的图像大小

我需要一个类似这个设置的功能

public void ResizeImageForWeb(string OriginalFile, string NewFile, int MaxWidth, int MaxHeight, int Quality)
{
// Resize Code

}

基本上,我是一名网页设计师,在尝试编写桌面应用程序时迷失了方向。

【问题讨论】:

  • 图片质量,1到100表示​​jpg的压缩方式
  • 请注意,您询问的是用 C# 编写的 GDI+ 调整大小函数,而不是 C# 调整大小函数。
  • 谢谢,我看到你更新了标题,所以我也加了一点。

标签: c# image gdi+ resize


【解决方案1】:

从谷歌快速搜索找到这个小snippet

【讨论】:

  • 这是我在这种情况下使用的 sn-p。 +1。
  • 如何使用该功能使文件变小?
  • @Tyler,sn-p 使用我的代码使用的相同功能(Image.GetThumbnailImage,Image.Save),因此会有相同的限制。
  • +1 “翻转”图像技巧正是我一直在寻找的缺失部分。使图像分辨率更高。否则你会得到一个模糊的图像。
  • 请不要发布到 sn-ps 的链接,它们往往会丢失(因为这个有...)
【解决方案2】:

这是我用来调整用户上传的图像大小以创建缩略图或只是强制执行大小限制的代码。它没有解决图片质量问题,但它是一个开始。

// uses System.Drawing namespace
public class ImageResizer
{
    public bool ResizeImage(string fullFileName, int maxHeight, int maxWidth)
    {
        return this.ResizeImage(fullFileName, maxHeight, maxWidth, fullFileName);
    }

    public bool ResizeImage(string fullFileName, int maxHeight, int maxWidth, string newFileName)
    {
        using (Image originalImage = Image.FromFile(fullFileName))
        {
            int height = originalImage.Height;
            int width = originalImage.Width;
            int newHeight = maxHeight;
            int newWidth = maxWidth;

            if (height > maxHeight || width > maxWidth)
            {
                if (height > maxHeight)
                {
                    newHeight = maxHeight;
                    float temp = ((float)width / (float)height) * (float)maxHeight;
                    newWidth = Convert.ToInt32(temp);

                    height = newHeight;
                    width = newWidth;
                }

                if (width > maxWidth)
                {
                    newWidth = maxWidth;
                    float temp = ((float)height / (float)width) * (float)maxWidth;
                    newHeight = Convert.ToInt32(temp);
                }

                Image.GetThumbnailImageAbort abort = new Image.GetThumbnailImageAbort(ThumbnailCallback);
                using (Image resizedImage = originalImage.GetThumbnailImage(newWidth, newHeight, abort, System.IntPtr.Zero))
                {
                    resizedImage.Save(newFileName);
                }

                return true;
            }
            else if (fullFileName != newFileName)
            {
                // no resizing necessary, but need to create new file 
                originalImage.Save(newFileName);
            }
        }

        return false;
    }

    private bool ThumbnailCallback()
    {
        return false;
    }
}

【讨论】:

【解决方案3】:

使用 Graphics.DrawImage()。 GetThumbnailImage() 将从 jpeg 文件返回一个 120x120(或更小)的嵌入缩略图。超过这个尺寸的任何东西都将是可怕的。

请参阅http://nathanaeljones.com/163/20-image-resizing-pitfalls/ 了解要使用的适当设置。

【讨论】:

    【解决方案4】:

    我当然不会使用 GetThumbnailImage,因为它会令人震惊 - 为了在不使用 DX 或 OpenL 等的情况下获得良好的分辨率,我会使用以下类似的东西(来自我自己在许多 Windows 应用程序中使用的图形库 - 我已经分享这之前几次,所以可能会有变体漂浮在网上)。这里有 3 种方法 - GetNonIndexedPixelFormat 方法用于在传递无法处理的像素格式时阻止 GDI 崩溃(cmets 解释它)。第一个允许按一个因子缩放(缩放),最后一个允许在保持纵横比的同时进行固定大小的重新缩放(但如果您想倾斜它,可以轻松修改)。享受:

        /// <summary>
        /// Scale Image By A Percentage - Scale Factor between 0 and 1.
        /// </summary>
        /// <param name="originalImg">Image: Image to scale</param>
        /// <param name="ZoomFactor">Float: Sclae Value - 0 to 1 are the usual values</param>
        /// <returns>Image: Scaled Image</returns>
        public static Image ScaleByPercent(Image originalImg, float ZoomFactor)
        {    
            int destWidth = (int)((float)originalImg.Width * ZoomFactor);
            int destHeight = (int)((float)originalImg.Height * ZoomFactor);
    
            Bitmap bmPhoto = new Bitmap(destWidth, destHeight, GetNonIndexedPixelFormat(originalImg)); // PixelFormat.Format24bppRgb);
    
            bmPhoto.SetResolution(originalImg.HorizontalResolution,  originalImg.VerticalResolution);
    
            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
    
            grPhoto.DrawImage(originalImg,
                new Rectangle(0, 0, destWidth, destHeight),
                new Rectangle(0, 0, originalImg.Width, originalImg.Height),
                GraphicsUnit.Pixel);
    
            grPhoto.Dispose();
            return bmPhoto;
        }
    
        /// <summary>
        /// Gets the closest non-indexed pixel format
        /// </summary>
        /// <param name="originalImage">Image: Original image</param>
        /// <returns>PixelFormat: Closest non-pixel image format</returns>
        public static PixelFormat GetNonIndexedPixelFormat(Image originalImage)
        {
            /*
             * These formats cause an error when creating a GDI Graphics Oblect, so must be converted to non Indexed
             * Error is "A graphics object cannot be created from an image that has an indexed pixel format"
             * 
                PixelFormat.Undefined 
                PixelFormat.DontCare 
                PixelFormat.1bppIndexed
                PixelFormat.4bppIndexed
                PixelFormat.8bppIndexed
                PixelFormat.16bppGrayScale
                PixelFormat.16bppARGB1555
             * 
             * An attempt is made to use the closest (i.e. smallest fitting) format that will hold the palette.
             */
    
            switch (originalImage.PixelFormat)
            {
                case PixelFormat.Undefined: 
                    //This is also the same Enumation as PixelFormat.DontCare:
                    return PixelFormat.Format24bppRgb;
                case PixelFormat.Format1bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format4bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format8bppIndexed:
                    return PixelFormat.Format16bppRgb555;
                case PixelFormat.Format16bppGrayScale:
                    return PixelFormat.Format16bppArgb1555;
                case PixelFormat.Format32bppArgb:
                    return PixelFormat.Format24bppRgb;                
                default:
                    return originalImage.PixelFormat;
            }
        }
    
        /// <summary>
        /// Resize image keeping aspect ratio.
        /// </summary>
        /// <param name="originalImg">Image: Image to scale</param>
        /// <param name="Width">Int: Required width in pixels</param>
        /// <param name="Height">Int: Required height in pixels</param>
        /// <param name="BackgroundColour">Color: Background colour</param>
        /// <returns>Image: Scaled Image</returns>
        public static Image Resize(Image originalImg, int Width, int Height, Color BackgroundColour)
        {
            int destX = 0;
            int destY = 0;
    
            float nPercent = 0f;
    
            float nPercentW = ((float)Width / (float)originalImg.Width);
            float nPercentH = ((float)Height / (float)originalImg.Height);
    
            if (nPercentH < nPercentW)
            {
                nPercent = nPercentH;
                destX = System.Convert.ToInt16(((float)Width - ((float)originalImg.Width * nPercent)) / 2f);
            }
            else
            {
                nPercent = nPercentW;
                destY = System.Convert.ToInt16(((float)Height - ((float)originalImg.Height * nPercent)) / 2f);
            }
    
            int destWidth = (int)(originalImg.Width * nPercent);
            int destHeight = (int)(originalImg.Height * nPercent);
    
            Bitmap bmPhoto = new Bitmap(Width, Height, GetNonIndexedPixelFormat(originalImg)); // PixelFormat.Format24bppRgb);
    
            bmPhoto.SetResolution(originalImg.HorizontalResolution, originalImg.VerticalResolution);
    
            Graphics grPhoto = Graphics.FromImage(bmPhoto);
            grPhoto.Clear(BackgroundColour);
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
    
            grPhoto.DrawImage(originalImg,
                new Rectangle(destX, destY, destWidth, destHeight),
                new Rectangle(0, 0, originalImg.Width, originalImg.Height), GraphicsUnit.Pixel);
    
            grPhoto.Dispose();
            return bmPhoto;
        }
    

    【讨论】:

    • +1 用于在此处报告代码,而不是链接到可能随时间过期的外部资源。实际上,已接受答案中的链接不再起作用。谢谢。
    猜你喜欢
    • 2013-11-28
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2020-03-23
    相关资源
    最近更新 更多