C# GDI+ Image Resize Function

前端 未结 4 1311
执念已碎
执念已碎 2020-12-22 04:35

So my logic is flawed and I need a better and correct way to resize an image in my c# app

I need a function similar to this setup

public void ResizeI         


        
4条回答
  •  南笙
    南笙 (楼主)
    2020-12-22 05:20

    I would certainly not use GetThumbnailImage as it would be shocking - for good resolution without resorting to DX or OpenL etc, I'd use something like the following (from my own graphics library I use in many windows apps - I have shared this a few times before so there may be variants float around the net). There are 3 methods here - the GetNonIndexedPixelFormat method is used to stop GDI crashing when passed pixel formats it can't handle (comments explain it). The first allows scaling by a factor (Zoom) and the last allows fixed size rescaling whilst keeping the aspect ratio (but can easily be modified if you want to skew it instead). Enjoy:

        /// 
        /// Scale Image By A Percentage - Scale Factor between 0 and 1.
        /// 
        /// Image: Image to scale
        /// Float: Sclae Value - 0 to 1 are the usual values
        /// Image: Scaled Image
        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;
        }
    
        /// 
        /// Gets the closest non-indexed pixel format
        /// 
        /// Image: Original image
        /// PixelFormat: Closest non-pixel image format
        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;
            }
        }
    
        /// 
        /// Resize image keeping aspect ratio.
        /// 
        /// Image: Image to scale
        /// Int: Required width in pixels
        /// Int: Required height in pixels
        /// Color: Background colour
        /// Image: Scaled Image
        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;
        }
    

提交回复
热议问题