c # Thay đổi kích thước hình ảnh thành kích thước khác mà vẫn giữ nguyên tỷ lệ khung hình


80

Tôi đang cố gắng thay đổi kích thước hình ảnh trong khi vẫn giữ nguyên tỷ lệ khung hình từ hình ảnh gốc để hình ảnh mới trông không bị bóp méo.

ví dụ:

Chuyển đổi hình ảnh 150 * 100 thành hình ảnh 150 * 150.
Chiều cao thêm 50 pixel cần được đệm bằng màu nền trắng.

Đây là mã hiện tại tôi đang sử dụng.

Nó hoạt động tốt để thay đổi kích thước nhưng thay đổi tỷ lệ khung hình của hình ảnh gốc sẽ làm hỏng hình ảnh mới.

private void resizeImage(string path, string originalFilename, 
                         int width, int height)
    {
        Image image = Image.FromFile(path + originalFilename);

        System.Drawing.Image thumbnail = new Bitmap(width, height);
        System.Drawing.Graphics graphic = 
                     System.Drawing.Graphics.FromImage(thumbnail);

        graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphic.SmoothingMode = SmoothingMode.HighQuality;
        graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
        graphic.CompositingQuality = CompositingQuality.HighQuality;

        graphic.DrawImage(image, 0, 0, width, height);

        System.Drawing.Imaging.ImageCodecInfo[] info =
                         ImageCodecInfo.GetImageEncoders();
        EncoderParameters encoderParameters;
        encoderParameters = new EncoderParameters(1);
        encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
                         100L);            
        thumbnail.Save(path + width + "." + originalFilename, info[1], 
                         encoderParameters);
    }

CHỈNH SỬA: Tôi muốn hình ảnh được đệm thay vì bị cắt

Câu trả lời:


114

Điều này nên làm điều đó.

private void resizeImage(string path, string originalFilename, 
                     /* note changed names */
                     int canvasWidth, int canvasHeight, 
                     /* new */
                     int originalWidth, int originalHeight)
{
    Image image = Image.FromFile(path + originalFilename);

    System.Drawing.Image thumbnail = 
        new Bitmap(canvasWidth, canvasHeight); // changed parm names
    System.Drawing.Graphics graphic = 
                 System.Drawing.Graphics.FromImage(thumbnail);

    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphic.SmoothingMode = SmoothingMode.HighQuality;
    graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
    graphic.CompositingQuality = CompositingQuality.HighQuality;

    /* ------------------ new code --------------- */

    // Figure out the ratio
    double ratioX = (double) canvasWidth / (double) originalWidth;
    double ratioY = (double) canvasHeight / (double) originalHeight;
    // use whichever multiplier is smaller
    double ratio = ratioX < ratioY ? ratioX : ratioY;

    // now we can get the new height and width
    int newHeight = Convert.ToInt32(originalHeight * ratio);
    int newWidth = Convert.ToInt32(originalWidth * ratio);

    // Now calculate the X,Y position of the upper-left corner 
    // (one of these will always be zero)
    int posX = Convert.ToInt32((canvasWidth - (originalWidth * ratio)) / 2);
    int posY = Convert.ToInt32((canvasHeight - (originalHeight * ratio)) / 2);

    graphic.Clear(Color.White); // white padding
    graphic.DrawImage(image, posX, posY, newWidth, newHeight);

    /* ------------- end new code ---------------- */

    System.Drawing.Imaging.ImageCodecInfo[] info =
                     ImageCodecInfo.GetImageEncoders();
    EncoderParameters encoderParameters;
    encoderParameters = new EncoderParameters(1);
    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
                     100L);            
    thumbnail.Save(path + newWidth + "." + originalFilename, info[1], 
                     encoderParameters);
}

Đã chỉnh sửa để thêm:

Những người muốn cải thiện mã này nên đưa nó vào phần nhận xét hoặc câu trả lời mới. Không chỉnh sửa mã này trực tiếp.


2
Bạn chỉ cần thắc mắc về các thông số originalWidth và originalHeight, tại sao bạn lại cần chúng khi bạn chỉ có thể lấy thông tin đó từ hình ảnh? (Tôi đã chỉnh sửa mã của bạn trong quá khứ, trước khi tôi có được phép bình luận, lời xin lỗi của tôi cho điều đó)
Mendel

@mendel - vâng, điều đó cũng sẽ hoạt động. Nhưng trong câu hỏi ban đầu, anh ta đã biết chiều cao và chiều rộng, vậy tại sao phải tính toán lại chúng một lần nữa?
egrunin

1
tôi đã thử điều này trên hình ảnh 1024 * 768 để chuyển đổi thành hình ảnh 500 * 500 - hình ảnh bị méo. Tôi đang tìm kiếm thuật toán giống như của CMS wordpress nơi hình ảnh không bị biến dạng khi chúng được tạo kích thước nhỏ hơn (tuy nhiên có một số ảnh cắt từ các bên).
yogihosting

@yogihosting đăng câu hỏi về sự cố của bạn, bao gồm mã của bạn, thậm chí có thể là liên kết đến hình ảnh thử nghiệm. Điều này đang hoạt động cho những người khác, vì vậy chúng tôi sẽ cần xem điều gì khác biệt với bạn.
egrunin

1
@egrunin Tôi khuyên bạn nên sử dụng Path.Combine(path, originalFileName)khi tải hình ảnh gốc. Tương tự khi lưu hình thu nhỏ ở cuối.
Paul Karam

81

Tôi đã tìm ra cách thay đổi kích thước VÀ đệm hình ảnh bằng cách tìm hiểu từ Bài viết CodeProject này .

static Image FixedSize(Image imgPhoto, int Width, int Height)
    {
        int sourceWidth = imgPhoto.Width;
        int sourceHeight = imgPhoto.Height;
        int sourceX = 0;
        int sourceY = 0;
        int destX = 0;
        int destY = 0;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)Width / (float)sourceWidth);
        nPercentH = ((float)Height / (float)sourceHeight);
        if (nPercentH < nPercentW)
        {
            nPercent = nPercentH;
            destX = System.Convert.ToInt16((Width -
                          (sourceWidth * nPercent)) / 2);
        }
        else
        {
            nPercent = nPercentW;
            destY = System.Convert.ToInt16((Height -
                          (sourceHeight * nPercent)) / 2);
        }

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap bmPhoto = new Bitmap(Width, Height,
                          PixelFormat.Format24bppRgb);
        bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                         imgPhoto.VerticalResolution);

        Graphics grPhoto = Graphics.FromImage(bmPhoto);
        grPhoto.Clear(Color.Red);
        grPhoto.InterpolationMode =
                InterpolationMode.HighQualityBicubic;

        grPhoto.DrawImage(imgPhoto,
            new Rectangle(destX, destY, destWidth, destHeight),
            new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
            GraphicsUnit.Pixel);

        grPhoto.Dispose();
        return bmPhoto;
    }

1
@bobek chỉ cần đóng ảnh gốc imgPhoto.Dispose ();
cướp

1
Mã đẹp! Thậm chí còn gọn gàng hơn nếu sử dụng 'using pattern' cho Graphics.FromImage (bmPhoto); và sourceX và sourceY biến loại bỏ và thiết lập để 0 đen trong 'Hình chữ nhật mới (0, 0, sourceWidth, sourceHeight)
Patrick từ đội NDepend

chính xác những gì tôi cần;) đặc biệt hữu ích khi bạn cần chuyển một tham số hình ảnh thay vì đường dẫn thực tế.
Pinte Dani

2
Tốt mã, tuy nhiên tôi đề nghị sử dụng Color.White hơn Color.Red
Ahmad

27

Tôi sử dụng phương pháp sau để tính kích thước hình ảnh mong muốn:

using System.Drawing;
public static Size ResizeKeepAspect(this Size src, int maxWidth, int maxHeight, bool enlarge = false)
{
    maxWidth = enlarge ? maxWidth : Math.Min(maxWidth, src.Width);
    maxHeight = enlarge ? maxHeight : Math.Min(maxHeight, src.Height);

    decimal rnd = Math.Min(maxWidth / (decimal)src.Width, maxHeight / (decimal)src.Height);
    return new Size((int)Math.Round(src.Width * rnd), (int)Math.Round(src.Height * rnd));
}

Điều này đặt vấn đề về tỷ lệ co và kích thước trong một phương pháp riêng.


Điều gì xảy ra nếu tôi muốn thực hiện một "điền"? Đó là những gì enlargekhông?
Mathias Lykkegaard Lorenzen

@MathiasLykkegaardLorenzen thường bạn chỉ bị thu hẹp hình ảnh vì mở rộng phương tiện làm giảm chất lượng - vì vậy tôi đã thêm tham số tùy chọn này nếu bạn muốn làm điều đó anyway
Fubo

9

Để có kết quả nhanh hơn, bạn có thể tìm thấy hàm lấy kích thước trong resultSize:

Size original = new Size(640, 480);

int maxSize = 100;

float percent = (new List<float> { (float)maxSize / (float)original.Width , (float)maxSize  / (float)original.Height }).Min();

Size resultSize = new Size((int)Math.Floor(original.Width * percent), (int)Math.Floor(original.Height * percent));

Sử dụng Linqđể giảm thiểu biến và tính toán lại, cũng như các if/elsecâu lệnh không cần thiết


Đây là một giải pháp tuyệt vời! Rất ngắn gọn và nhỏ. Tôi đã sử dụng phiên bản đã sửa đổi của cái này cùng với System.Web.Helpers.WebImage để thay đổi kích thước hình ảnh theo tỷ lệ nhanh chóng. Bạn đã làm rất tốt!
Halcyon

If/elsesẽ tốt hơn so với phân bổ một danh sách, Math.Minquá là một lựa chọn
Surya Pratap

7

Chỉ cần khái quát nó xuống tỷ lệ và kích thước, nội dung hình ảnh có thể được thực hiện bên ngoài chức năng này

public static d.RectangleF ScaleRect(d.RectangleF dest, d.RectangleF src, 
  bool keepWidth, bool keepHeight)  
{
    d.RectangleF destRect = new d.RectangleF();

    float sourceAspect = src.Width / src.Height;
    float destAspect = dest.Width / dest.Height;

    if (sourceAspect > destAspect)
    {
        // wider than high keep the width and scale the height
        destRect.Width = dest.Width;
        destRect.Height = dest.Width / sourceAspect;

        if (keepHeight)
        {
            float resizePerc = dest.Height / destRect.Height;
            destRect.Width = dest.Width * resizePerc;
            destRect.Height = dest.Height;
        }
    }
    else
    {
        // higher than wide – keep the height and scale the width
        destRect.Height = dest.Height;
        destRect.Width = dest.Height * sourceAspect;

        if (keepWidth)
        {
            float resizePerc = dest.Width / destRect.Width;
            destRect.Width = dest.Width;
            destRect.Height = dest.Height * resizePerc;
        }

    }

    return destRect;
}

Đó là một ý tưởng tuyệt vời tách rời mối quan tâm này. Bạn có thể sử dụng SizeF thay vì RectangleF.
Davi Fiamenghi

6

Tôi cũng sẽ thêm mã của mình ở đây. Mã này sẽ cho phép bạn thay đổi kích thước hình ảnh có hoặc không có tỷ lệ khung hình được thực thi hoặc thay đổi kích thước bằng đệm. Đây là phiên bản sửa đổi của mã của egrunin.

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var path = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;
            ResizeImage(path, "large.jpg", path, "new.jpg", 100, 100, true, true);
        }

        /// <summary>Resizes an image to a new width and height.</summary>
        /// <param name="originalPath">The folder which holds the original image.</param>
        /// <param name="originalFileName">The file name of the original image.</param>
        /// <param name="newPath">The folder which will hold the resized image.</param>
        /// <param name="newFileName">The file name of the resized image.</param>
        /// <param name="maximumWidth">When resizing the image, this is the maximum width to resize the image to.</param>
        /// <param name="maximumHeight">When resizing the image, this is the maximum height to resize the image to.</param>
        /// <param name="enforceRatio">Indicates whether to keep the width/height ratio aspect or not. If set to false, images with an unequal width and height will be distorted and padding is disregarded. If set to true, the width/height ratio aspect is maintained and distortion does not occur.</param>
        /// <param name="addPadding">Indicates whether fill the smaller dimension of the image with a white background. If set to true, the white padding fills the smaller dimension until it reach the specified max width or height. This is used for maintaining a 1:1 ratio if the max width and height are the same.</param>
        private static void ResizeImage(string originalPath, string originalFileName, string newPath, string newFileName, int maximumWidth, int maximumHeight, bool enforceRatio, bool addPadding)
        {
            var image = Image.FromFile(originalPath + "\\" + originalFileName);
            var imageEncoders = ImageCodecInfo.GetImageEncoders();
            EncoderParameters encoderParameters = new EncoderParameters(1);
            encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
            var canvasWidth = maximumWidth;
            var canvasHeight = maximumHeight;
            var newImageWidth = maximumWidth;
            var newImageHeight = maximumHeight;
            var xPosition = 0;
            var yPosition = 0;


            if (enforceRatio)
            {
                var ratioX = maximumWidth / (double)image.Width;
                var ratioY = maximumHeight / (double)image.Height;
                var ratio = ratioX < ratioY ? ratioX : ratioY;
                newImageHeight = (int)(image.Height * ratio);
                newImageWidth = (int)(image.Width * ratio);

                if (addPadding)
                {
                    xPosition = (int)((maximumWidth - (image.Width * ratio)) / 2);
                    yPosition = (int)((maximumHeight - (image.Height * ratio)) / 2);
                }
                else
                {
                    canvasWidth = newImageWidth;
                    canvasHeight = newImageHeight;                  
                }
            }

            var thumbnail = new Bitmap(canvasWidth, canvasHeight);
            var graphic = Graphics.FromImage(thumbnail);

            if (enforceRatio && addPadding)
            {
                graphic.Clear(Color.White);
            }

            graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
            graphic.SmoothingMode = SmoothingMode.HighQuality;
            graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
            graphic.CompositingQuality = CompositingQuality.HighQuality;
            graphic.DrawImage(image, xPosition, yPosition, newImageWidth, newImageHeight);

            thumbnail.Save(newPath + "\\" + newFileName, imageEncoders[1], encoderParameters);
        }
    }
}

Hãy nhớ thêm một tham chiếu đến System.Drawing DLL.
Doug

Đoạn mã này xoay hình ảnh 90 độ - hình thu nhỏ được xoay so với hình gốc - tại sao?
user2709214

5

Đây là một phương pháp mở rộng ít cụ thể hơn hoạt động với Hình ảnh thay vì thực hiện tải và lưu cho bạn. Nó cũng cho phép bạn chỉ định phương pháp nội suy và hiển thị chính xác các cạnh khi bạn sử dụng nội suy NearestNeighbour.

Hình ảnh sẽ được hiển thị trong giới hạn của khu vực bạn chỉ định để bạn luôn biết chiều rộng và chiều cao đầu ra của mình. ví dụ:

Được mở rộng trong giới hạn

namespace YourApp
{
    #region Namespaces
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Drawing.Drawing2D;
    #endregion

    /// <summary>Generic helper functions related to graphics.</summary>
    public static class ImageExtensions
    {
        /// <summary>Resizes an image to a new width and height value.</summary>
        /// <param name="image">The image to resize.</param>
        /// <param name="newWidth">The width of the new image.</param>
        /// <param name="newHeight">The height of the new image.</param>
        /// <param name="mode">Interpolation mode.</param>
        /// <param name="maintainAspectRatio">If true, the image is centered in the middle of the returned image, maintaining the aspect ratio of the original image.</param>
        /// <returns>The new image. The old image is unaffected.</returns>
        public static Image ResizeImage(this Image image, int newWidth, int newHeight, InterpolationMode mode = InterpolationMode.Default, bool maintainAspectRatio = false)
        {
            Bitmap output = new Bitmap(newWidth, newHeight, image.PixelFormat);

            using (Graphics gfx = Graphics.FromImage(output))
            {
                gfx.Clear(Color.FromArgb(0, 0, 0, 0));
                gfx.InterpolationMode = mode;
                if (mode == InterpolationMode.NearestNeighbor)
                {
                    gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    gfx.SmoothingMode = SmoothingMode.HighQuality;
                }

                double ratioW = (double)newWidth / (double)image.Width;
                double ratioH = (double)newHeight / (double)image.Height;
                double ratio = ratioW < ratioH ? ratioW : ratioH;
                int insideWidth = (int)(image.Width * ratio);
                int insideHeight = (int)(image.Height * ratio);

                gfx.DrawImage(image, new Rectangle((newWidth / 2) - (insideWidth / 2), (newHeight / 2) - (insideHeight / 2), insideWidth, insideHeight));
            }

            return output;
        }
    }
}

1
Tham số cho duy trìAspectRatio không được sử dụng.
Haukman

4

Lưu ý: mã này thay đổi kích thước và loại bỏ mọi thứ bên ngoài tỷ lệ khung hình thay vì chèn nó ..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace MyPhotos.Common
{
    public class ThumbCreator
    {

        public enum VerticalAlign
        {
            Top,
            Middle,
            Bottom
        }

        public enum HorizontalAlign
        {
            Left,
            Middle,
            Right
        }

        public void Convert(string sourceFile, string targetFile, ImageFormat targetFormat, int height, int width, VerticalAlign valign, HorizontalAlign halign)
        {
            using (Image img = Image.FromFile(sourceFile))
            {
                using (Image targetImg = Convert(img, height, width, valign, halign))
                {
                    string directory = Path.GetDirectoryName(targetFile);
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }
                    if (targetFormat == ImageFormat.Jpeg)
                    {
                        SaveJpeg(targetFile, targetImg, 100);
                    }
                    else
                    {
                        targetImg.Save(targetFile, targetFormat);
                    }
                }
            }
        }

        /// <summary> 
        /// Saves an image as a jpeg image, with the given quality 
        /// </summary> 
        /// <param name="path">Path to which the image would be saved.</param> 
        // <param name="quality">An integer from 0 to 100, with 100 being the 
        /// highest quality</param> 
        public static void SaveJpeg(string path, Image img, int quality)
        {
            if (quality < 0 || quality > 100)
                throw new ArgumentOutOfRangeException("quality must be between 0 and 100.");


            // Encoder parameter for image quality 
            EncoderParameter qualityParam =
                new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            // Jpeg image codec 
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

            EncoderParameters encoderParams = new EncoderParameters(1);
            encoderParams.Param[0] = qualityParam;

            img.Save(path, jpegCodec, encoderParams);
        }

        /// <summary> 
        /// Returns the image codec with the given mime type 
        /// </summary> 
        private static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            // Get image codecs for all image formats 
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();

            // Find the correct image codec 
            for (int i = 0; i < codecs.Length; i++)
                if (codecs[i].MimeType == mimeType)
                    return codecs[i];
            return null;
        }

        public Image Convert(Image img, int height, int width, VerticalAlign valign, HorizontalAlign halign)
        {
            Bitmap result = new Bitmap(width, height);
            using (Graphics g = Graphics.FromImage(result))
            {
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                float ratio = (float)height / (float)img.Height;
                int temp = (int)((float)img.Width * ratio);
                if (temp == width)
                {
                    //no corrections are needed!
                    g.DrawImage(img, 0, 0, width, height);
                    return result;
                }
                else if (temp > width)
                {
                    //den e för bred!
                    int overFlow = (temp - width);
                    if (halign == HorizontalAlign.Middle)
                    {
                        g.DrawImage(img, 0 - overFlow / 2, 0, temp, height);
                    }
                    else if (halign == HorizontalAlign.Left)
                    {
                        g.DrawImage(img, 0, 0, temp, height);
                    }
                    else if (halign == HorizontalAlign.Right)
                    {
                        g.DrawImage(img, -overFlow, 0, temp, height);
                    }
                }
                else
                {
                    //den e för hög!
                    ratio = (float)width / (float)img.Width;
                    temp = (int)((float)img.Height * ratio);
                    int overFlow = (temp - height);
                    if (valign == VerticalAlign.Top)
                    {
                        g.DrawImage(img, 0, 0, width, temp);
                    }
                    else if (valign == VerticalAlign.Middle)
                    {
                        g.DrawImage(img, 0, -overFlow / 2, width, temp);
                    }
                    else if (valign == VerticalAlign.Bottom)
                    {
                        g.DrawImage(img, 0, -overFlow, width, temp);
                    }
                }
            }
            return result;
        }
    }
}

@Peter Điều này không tuân theo chiều rộng / chiều cao kích thước được xác định ban đầu mà tôi đã chuyển cho hàm. Thay vào đó, tôi nhận được một hình ảnh rất mỏng và dài, bất kỳ ý tưởng nào để khắc phục điều này?
Idan Shechter

@IdanShechter đây là một câu trả lời cũ cũ (tôi đã không sử dụng mã này trong nhiều năm), bạn có thể cung cấp cho tôi một ví dụ và tôi có thể giúp bạn.
Peter

@Peter Cảm ơn, tôi thực sự đang sử dụng ImageProcessor, nhưng tôi nhận được một ngoại lệ: stackoverflow.com/questions/51280935/…
Idan Shechter,

4

// This allows us to resize the image. It prevents skewed images and 
// also vertically long images caused by trying to maintain the aspect 
// ratio on images who's height is larger than their width

public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)

{
    System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFile);

    // Prevent using images internal thumbnail
    FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
    FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

    if (OnlyResizeIfWider)
    {
        if (FullsizeImage.Width <= NewWidth)
        {
            NewWidth = FullsizeImage.Width;
        }
    }

    int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
    if (NewHeight > MaxHeight)
    {
        // Resize with height instead
        NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
        NewHeight = MaxHeight;
    }

    System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);

    // Clear handle to original file so that we can overwrite it if necessary
    FullsizeImage.Dispose();

    // Save resized picture
    NewImage.Save(NewFile);
}


Bạn có một ví dụ không sử dụng GetThumbnailImage không? Tôi muốn kiểm soát chất lượng và các cài đặt khác theo cách thủ công.
sf.

1

Duy trì Tỷ lệ khía cạnh và loại bỏ hộp thư và Hộp cột.

static Image FixedSize(Image imgPhoto, int Width, int Height)
    {
        int sourceWidth = imgPhoto.Width;
        int sourceHeight = imgPhoto.Height;
        int X = 0;
        int Y = 0;

        float nPercent = 0;
        float nPercentW = 0;
        float nPercentH = 0;

        nPercentW = ((float)Width / (float)sourceWidth);
        nPercentH = ((float)Height / (float)sourceHeight);
        if (nPercentH < nPercentW)
        {
            nPercent = nPercentH;
        }
        else
        {
            nPercent = nPercentW;
        }

        int destWidth = (int)(sourceWidth * nPercent);
        int destHeight = (int)(sourceHeight * nPercent);

        Bitmap bmPhoto = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);

        bmPhoto.SetResolution(imgPhoto.HorizontalResolution,
                                         imgPhoto.VerticalResolution);

        Graphics grPhoto = Graphics.FromImage(bmPhoto);

        grPhoto.DrawImage(imgPhoto,
                new Rectangle(X, Y, destWidth, destHeight),
                new Rectangle(X, Y, sourceWidth, sourceHeight),
                GraphicsUnit.Pixel);

        grPhoto.Dispose();
        return bmPhoto;
    }

1
public static void resizeImage_n_save(Stream sourcePath, string targetPath, int requiredSize)
    {
        using (var image = System.Drawing.Image.FromStream(sourcePath))
        {
            double ratio = 0;

            var newWidth = 0;
            var newHeight = 0;
            double w = Convert.ToInt32(image.Width);
            double h = Convert.ToInt32(image.Height);
            if (w > h)
            {
                ratio = h / w * 100;
                newWidth = requiredSize;
                newHeight = Convert.ToInt32(requiredSize * ratio / 100);
            }
            else
            {
                ratio = w / h * 100;
                newHeight = requiredSize;
                newWidth = Convert.ToInt32(requiredSize * ratio / 100);
            }

            //   var newWidth = (int)(image.Width * scaleFactor);
            // var newHeight = (int)(image.Height * scaleFactor);
            var thumbnailImg = new Bitmap(newWidth, newHeight);
            var thumbGraph = Graphics.FromImage(thumbnailImg);
            thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
            thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
            thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;
            var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);

            thumbGraph.DrawImage(image, imageRectangle);
            thumbnailImg.Save(targetPath, image.RawFormat);

            //var img = FixedSize(image, requiredSize, requiredSize);
            //img.Save(targetPath, image.RawFormat);

        }
    }

0

Tôi chỉ viết điều này vì không có câu trả lời nào ở đây đủ đơn giản. Bạn có thể thay thế mã cứng 128 cho bất cứ thứ gì bạn muốn hoặc dựa trên kích thước của hình ảnh gốc. Tất cả những gì tôi muốn là thay đổi tỷ lệ hình ảnh thành hình ảnh 128x128, giữ nguyên tỷ lệ khung hình và căn giữa kết quả trong hình ảnh mới.

    private Bitmap CreateLargeIconForImage(Bitmap src)
    {
        Bitmap bmp = new Bitmap(128, 128);
        Graphics g = Graphics.FromImage(bmp);

        float scale = Math.Max((float)src.Width / 128.0f, (float)src.Height / 128.0f);
        PointF p = new PointF(128.0f - ((float)src.Width / scale), 128.0f - ((float)src.Height / scale));
        SizeF size = new SizeF((float)src.Width / scale, (float)src.Height / scale);

        g.DrawImage(src, new RectangleF(p, size));

        return bmp;
    }

0

Tôi đã tạo một phương pháp mở rộng đơn giản hơn nhiều so với các câu trả lời được đăng. và tỷ lệ khung hình được áp dụng mà không cần cắt ảnh.

public static Image Resize(this Image image, int width, int height) {
     var scale = Math.Min(height / (float)image.Height, width / (float)image.Width);
     return image.GetThumbnailImage((int)(image.Width * scale), (int)(image.Height * scale), () => false, IntPtr.Zero);
}

Ví dụ sử dụng:

using (var img = Image.FromFile(pathToOriginalImage)) {
    using (var thumbnail = img.Resize(60, 60)){
        // Here you can do whatever you need to do with thumnail
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.