c#アスペクト比を維持しながら、異なるサイズにサイズ変更する画像


81

新しい画像が押しつぶされて見えないように、元の画像のアスペクト比を維持しながら画像のサイズを変更しようとしています。

例えば:

150 * 100の画像を150 * 150の画像に変換します。
高さの余分な50ピクセルは、白い背景色で埋める必要があります。

これは私が使用している現在のコードです。

サイズ変更には適していますが、元の画像のアスペクト比を変更すると、新しい画像が押しつぶされます。

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

編集:画像をトリミングする代わりにパディングしたい

回答:


115

これでうまくいくはずです。

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

追加するために編集:

このコードを改善したい人は、コメントまたは新しい答えにそれを入れるべきです。このコードを直接編集しないでください。


2
パラメータoriginalWidthとoriginalHeightについて疑問に思っているのですが、画像からその情報を取得できるのに、なぜそれらが必要なのですか?(私は過去にあなたのコードを編集しましたが、コメントする許可を得る前に、そのことについてお詫びし
ます

@ mendel-はい、それもうまくいくでしょう。しかし、元の質問では、彼はすでに高さと幅を知っていたのに、なぜそれらを再計算するのですか?
egrunin 2013

1
1024 * 768の画像でこれを試して500 * 500の画像に変換しました-画像が歪んでしまいます。ワードプレスCMSのようなアルゴリズムを探しています。このアルゴリズムでは、画像を小さくしても画像が歪むことはありません(ただし、側面からのトリミングがいくつかあります)。
yogihosting 2015

@yogihostingは、コードやテスト画像へのリンクなど、問題に関する質問を投稿します。これは他の人のために働いているので、私たちはあなたにとって何が違うのかを見る必要があります。
egrunin 2015

1
@egruninPath.Combine(path, originalFileName)元の画像を読み込むときに使用することをお勧めします。最後にサムネイルを保存する場合も同様です。
Paul Karam 2018

83

このCodeProjectの記事から学ぶことで、画像のサイズを変更してパディングする方法を見つけました。

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は元の画像を閉じるだけですimgPhoto.Dispose();
ロブ・

1
素敵なコード!Graphics.FromImage(bmPhoto);に「usingpattern」を使用するとさらにクリーンになります。そしてsourceXとsourceY変数は破棄され、 '新しいRectangle(0、0、sourceWidth、sourceHeight)'で0リテラルに設定
NDependのチームからのパトリック・

まさに私が必要としていたもの;)実際のパスの代わりに画像パラメータを渡す必要がある場合に特に役立ちます。
パイントダニ2015

2
良いコードですが、Color.RedではなくColor.Whiteを使用することをお勧めします
Ahmad

27

次の方法を使用して、目的の画像サイズを計算します。

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

これにより、アスペクト比と寸法の問題が別の方法になります。


「塗りつぶし」をしたい場合はどうすればよいですか?それは何enlargeですか?
Mathias LykkegaardLorenzen19年

あなたはとにかくそれをしたい場合、私は、このオプションのパラメータを追加したので、 -手段の品質の損失を拡大するため、通常、あなたが唯一の画像の縮小ん@MathiasLykkegaardLorenzen
fubo

9

より高速な結果を得るために、サイズを取得する関数は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));

Linq変数と再計算、および不要なif/elseステートメントを最小限に抑えるために使用します


これは素晴らしい解決策です!非常に簡潔で小さい。System.Web.Helpers.WebImageと一緒にこれの修正バージョンを使用して、画像のサイズをその場で比例的に変更しました。よくやった!
ハルシオン2016年

If/elseリストを割り当てるよりも良かったでしょう。Math.Minオプションもありました
Surya Pratap 2018

7

アスペクト比とサイズに一般化するだけで、この機能の外で画像処理を行うことができます

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;
}

これは、この懸念を分離するための優れたアイデアです。の代わりにSizeFを使用できますRectangleF
Davi Fiamenghi 2013年

6

ここにもコードを追加します。このコードを使用すると、アスペクト比を適用して、または適用せずに画像のサイズを変更したり、パディングを使用してサイズを変更したりできます。これは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);
        }
    }
}

System.DrawingDLLへの参照を追加することを忘れないでください。
ダグ

このコードは画像を90度回転します-サムネイルは元の画像と比較して回転します-なぜですか?
user27092 1420

5

これは、ロードと保存を行うのではなく、Imageで機能するあまり具体的でない拡張メソッドです。また、NearestNeighbour補間を使用すると、補間方法を指定してエッジを正しくレンダリングできます。

画像は指定した領域の範囲内でレンダリングされるため、出力の幅と高さを常に把握できます。例えば:

範囲内でスケーリング

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
mainmainAspectRatioのパラメーターは使用されません。
ハウクマン

4

注:このコードは、パディングする代わりに、アスペクト比以外のすべてのサイズを変更して削除します。

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これは、関数に渡した元の定義されたサイズの幅/高さに準拠していませんでした。代わりに非常にスリムで長い画像を取得しましたが、これを修正する方法はありますか?
Idan Shechter 2018

@IdanShechterこれは古い古い答えです(私は長年このコードを使用していません)、例を教えていただければ、私はあなたを助けることができるかもしれません。
ピーター

@Peterは、私が実際に画像プロセッサを使用していますが、私は例外を取得、ありがとう:stackoverflow.com/questions/51280935/...
IDANシェフター

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


GetThumbnailImageを使用しない例はありましたか?品質などの設定を手動で制御したいのですが。
平方フィート。

1

アスペクト比を維持し、レターボックスとピラーボックスを削除します。

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);

        }
    }

1

投稿された回答よりもはるかに単純な拡張メソッドを作成しました。アスペクト比は画像をトリミングせずに適用されます。

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

使用例:

using (var img = Image.FromFile(pathToOriginalImage)) {
    using (var thumbnail = img.Resize(60, 60)){
        // Here you can do whatever you need to do with thumnail
    }
}

0

私はこのcosを書いたばかりで、すでにここにある答えはどれも十分に単純ではありませんでした。ハードコードされた128を必要に応じて置き換えるか、元の画像のサイズに基づいて置き換えることができます。私が欲しかったのは、画像を128x128の画像に再スケーリングし、アスペクト比を維持し、結果を新しい画像の中央に配置することだけでした。

    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;
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.