Cara mengubah ukuran Gambar C #

288

As Size, Widthdan Heightadalah Get()properti dari System.Drawing.Image;
Bagaimana saya bisa mengubah ukuran objek gambar saat run-time dalam C #?

Saat ini, saya baru saja membuat Imagepenggunaan baru :

// objImage is the original Image
Bitmap objBitmap = new Bitmap(objImage, new Size(227, 171));
inutan
sumber
2
Bukan cara yang benar ... menggunakan interpolasi berkualitas rendah dan dapat menyebabkan aliran asli tetap terkunci selama durasi gambar bitmap baru ... Baca daftar ukuran lubang perangkap gambar sebelum melakukan solusi ukuran gambar Anda sendiri.
Sungai Lilith
2
Buang itu! Menggunakan () {} berfungsi!
Scott Coates
8
Jika jawaban ini membantu, pertimbangkan menandai jawaban yang diterima.
Joel
3
Tidak perlu menggunakan perpustakaan tambahan apa pun. Kode yang diposting di bawah oleh Mark berfungsi dengan baik.
Elmue
9
Siapa itu Mark? Saya gagal menemukan jawabannya, tetapi ada 3 komentar yang merujuknya.
Sinatr

Jawaban:

490

Ini akan melakukan pengubahan ukuran kualitas tinggi:

/// <summary>
/// Resize the image to the specified width and height.
/// </summary>
/// <param name="image">The image to resize.</param>
/// <param name="width">The width to resize to.</param>
/// <param name="height">The height to resize to.</param>
/// <returns>The resized image.</returns>
public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width,image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}
  • wrapMode.SetWrapMode(WrapMode.TileFlipXY) mencegah ghosting di sekitar batas gambar - pengubahan ukuran yang naif akan sampel piksel transparan di luar batas gambar, tetapi dengan mirroring gambar kita bisa mendapatkan sampel yang lebih baik (pengaturan ini sangat terlihat)
  • destImage.SetResolution mempertahankan DPI terlepas dari ukuran fisik - dapat meningkatkan kualitas saat mengurangi dimensi gambar atau saat mencetak
  • Pengomposisian mengontrol bagaimana piksel dicampur dengan latar belakang - mungkin tidak diperlukan karena kami hanya menggambar satu hal.
  • graphics.InterpolationMode menentukan bagaimana nilai menengah antara dua titik akhir dihitung
  • graphics.SmoothingMode menentukan apakah garis, kurva, dan tepi area yang diisi menggunakan perataan (juga disebut antialiasing) - mungkin hanya bekerja pada vektor
  • graphics.PixelOffsetMode mempengaruhi kualitas render saat menggambar gambar baru

Mempertahankan rasio aspek dibiarkan sebagai latihan untuk pembaca (sebenarnya, saya hanya tidak berpikir itu tugas fungsi untuk melakukan itu untuk Anda).

Juga, ini adalah artikel bagus yang menggambarkan beberapa jebakan dengan ukuran gambar. Fungsi di atas akan mencakup sebagian besar dari mereka, tetapi Anda masih harus khawatir tentang menyimpan .

Mpen
sumber
4
kode berfungsi dengan baik saat mengubah ukuran gambar tetapi meningkatkan ukuran dari 66KB menjadi 132 KB. Cangkul, bisakah saya menguranginya
chamara
3
@chamara Itu mungkin karena menghemat kualitas yang Anda pilih. Lihat msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx Coba kualitas = 90
mpen
3
@ kstubs Anda yakin. Bitmappada dasarnya hanya nama kelas, Anda dapat menyimpannya sebagai jenis file apa pun yang Anda suka.
buka
5
@dotNetBlackBelt Anda mungkin perlu menambahkan referensi System.Drawingdan menambahkanusing System.Drawing.Imaging;
mpen
2
Ini tidak akan mempertahankan rasio aspek asli bukan?
Kasper Skov
148

Tidak yakin apa yang sangat sulit tentang ini, lakukan apa yang Anda lakukan, gunakan konstruktor Bitmap yang kelebihan beban untuk membuat gambar berukuran kembali, satu-satunya hal yang Anda lewatkan adalah balas kembali ke tipe data Gambar:

    public static Image resizeImage(Image imgToResize, Size size)
    {
       return (Image)(new Bitmap(imgToResize, size));
    }

    yourImage = resizeImage(yourImage, new Size(50,50));
Mat
sumber
2
Tidakkah sebaiknya Anda membuangnya yourImagesebelum menugaskannya ke gambar baru?
Nick Shaw
3
Anda dapat membuangnya secara manual atau membiarkan pengumpul sampah melakukan pekerjaannya. Tidak penting.
Elmue
23
Kode ini tidak memberikan kontrol atas kualitas ukuran yang sangat penting. Lihatlah jawaban dari Markus.
Elmue
42

dalam pertanyaan ini , Anda akan memiliki beberapa jawaban, termasuk jawaban saya:

public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
 {
     Image imgPhoto = Image.FromFile(stPhotoPath); 

     int sourceWidth = imgPhoto.Width;
     int sourceHeight = imgPhoto.Height;

     //Consider vertical pics
    if (sourceWidth < sourceHeight)
    {
        int buff = newWidth;

        newWidth = newHeight;
        newHeight = buff;
    }

    int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
    float nPercent = 0, nPercentW = 0, nPercentH = 0;

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

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


    Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
                  PixelFormat.Format24bppRgb);

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

    Graphics grPhoto = Graphics.FromImage(bmPhoto);
    grPhoto.Clear(Color.Black);
    grPhoto.InterpolationMode =
        System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

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

    grPhoto.Dispose();
    imgPhoto.Dispose();
    return bmPhoto;
}
Vinzz
sumber
5
Anda lupa imgPhoto.Dispose (); file tetap digunakan
shrutyzet
1
Ini sangat membantu, dan saya menggunakan ini di aplikasi saya. Namun penting untuk dicatat bahwa algoritma ini tidak berfungsi dengan gambar transparan .. Ini mengubah semua piksel transparan menjadi hitam. Ini mungkin mudah untuk diperbaiki, tetapi itu hanya catatan untuk pengguna. :)
meme
1
Bukankah Anda seharusnya menyimpan gambar? imgPhoto.Save ()?
Whiplash
@meme Bisakah Anda memberikan tautan tentang cara memperbaiki latar belakang hitam itu untuk dokumen transparan.
Syed Mohamed
25

Mengapa tidak menggunakan System.Drawing.Image.GetThumbnailImagemetode ini?

public Image GetThumbnailImage(
    int thumbWidth, 
    int thumbHeight, 
    Image.GetThumbnailImageAbort callback, 
    IntPtr callbackData)

Contoh:

Image originalImage = System.Drawing.Image.FromStream(inputStream, true, true);
Image resizedImage = originalImage.GetThumbnailImage(newWidth, (newWidth * originalImage.Height) / originalWidth, null, IntPtr.Zero);
resizedImage.Save(imagePath, ImageFormat.Png);

Sumber: http://msdn.microsoft.com/en-us/library/system.drawing.image.getthumbnailimage.aspx

Lino Silva
sumber
6
Ini bukan cara yang benar untuk mengubah ukuran gambar. Ini menarik thumbnail dari jpg jika ada. Jika tidak ada, Anda tidak dapat mengontrol kualitas atau gambar baru. Juga, kode ini seperti memiliki kebocoran memori.
Robert Smith
1
@ Bobob Mengapa ini menyebabkan kebocoran memori?
pengguna
2
Apa pun di perpustakaan GDI masih berjalan tidak terkelola. Tanpa menggunakan pernyataan menggunakan atau membuang benda sesudahnya, mungkin butuh waktu lama bagi sistem untuk mengumpulkan sampah benda-benda itu dan membuat memori tersedia lagi.
Robert Smith
9
Seperti yang Anda katakan: Mungkin butuh waktu lama. Tapi ini BUKAN kebocoran memori. TIDAK AKAN menjadi kebocoran memori jika memori tidak akan pernah dibebaskan. Tapi ini adalah perilaku NORMAL dari pengumpul sampah yang membebaskan memori saat CPU menganggur. Pernyataan using () tidak mencegah kebocoran memori. Itu hanya membebaskan memori segera sementara pengumpul sampah membebaskan memori ketika punya waktu untuk melakukan itu. Itulah satu-satunya perbedaan dalam kasus khusus ini.
Elmue
Lihat perangkap ukuran gambar: nathanaeljones.com/blog/2009/20-image-resizing-pitfalls "Menggunakan GetThumbnailImage (). GetThumbnailImage () tampaknya merupakan pilihan yang jelas, dan banyak artikel merekomendasikan penggunaannya. Sayangnya, ia selalu mengambil jpeg yang disematkan. thumbnail jika ada. Beberapa foto memiliki ini, beberapa tidak - ini biasanya tergantung pada kamera Anda. Anda akan bertanya-tanya mengapa GetThumbnailImage berfungsi dengan baik pada beberapa foto, tetapi pada yang lain sangat kabur. GetThumbnailImage () tidak dapat diandalkan untuk foto yang lebih besar dari 10px oleh 10px karena alasan itu. "
Nick Painter
12

Anda dapat mencoba net-vips , ikatan C # untuk libvips . Ini adalah perpustakaan pemrosesan gambar yang malas, streaming, dan digerakkan oleh permintaan, sehingga dapat melakukan operasi seperti ini tanpa perlu memuat keseluruhan gambar.

Misalnya, ia hadir dengan thumbnailer gambar yang berguna:

Image image = Image.Thumbnail("image.jpg", 300, 300);
image.WriteToFile("my-thumbnail.jpg");

Ini juga mendukung pemangkasan cerdas, cara cerdas menentukan bagian paling penting dari gambar dan menjaganya tetap fokus saat memotong gambar. Sebagai contoh:

Image image = Image.Thumbnail("owl.jpg", 128, crop: "attention");
image.WriteToFile("tn_owl.jpg");

Di mana owl.jpgkomposisi di luar pusat:

Burung hantu

Memberikan hasil ini:

Tanaman pintar burung hantu

Pertama, menyusut gambar untuk mendapatkan sumbu vertikal hingga 128 piksel, kemudian memotong hingga 128 piksel menggunakan attentionstrategi. Yang ini mencari gambar untuk fitur yang mungkin menarik perhatian manusia, lihat Smartcrop()detailnya.

kleisauke
sumber
Ikatan Anda untuk libvips tampak hebat. Saya pasti akan melihat lib Anda. Terima kasih telah menyediakan ini untuk Pengembang C #!
FrenchTastic
Ini luar biasa! Saya tidak tahu perpustakaan pemrosesan gambar bisa terlihat sebagus ini.
dalvir
bagus! lebih baik daripada ImageMagick heavy
Moshe L
10

Ini akan -

  • Ubah ukuran lebar DAN tinggi tanpa perlu loop
  • Tidak melebihi dimensi asli gambar

//////////////

private void ResizeImage(Image img, double maxWidth, double maxHeight)
{
    double resizeWidth = img.Source.Width;
    double resizeHeight = img.Source.Height;

    double aspect = resizeWidth / resizeHeight;

    if (resizeWidth > maxWidth)
    {
        resizeWidth = maxWidth;
        resizeHeight = resizeWidth / aspect;
    }
    if (resizeHeight > maxHeight)
    {
        aspect = resizeWidth / resizeHeight;
        resizeHeight = maxHeight;
        resizeWidth = resizeHeight * aspect;
    }

    img.Width = resizeWidth;
    img.Height = resizeHeight;
}
Dominic
sumber
11
OP bertanya tentang System.Drawing.Image, di mana kode Anda tidak akan berfungsi karena properti 'Lebar' dan 'Tinggi' tidak dapat diselesaikan. Namun, itu akan bekerja untuk System.Windows.Controls.Image.
mmmdreg
10
public static Image resizeImage(Image image, int new_height, int new_width)
{
    Bitmap new_image = new Bitmap(new_width, new_height);
    Graphics g = Graphics.FromImage((Image)new_image );
    g.InterpolationMode = InterpolationMode.High;
    g.DrawImage(image, 0, 0, new_width, new_height);
    return new_image;
}
NeoSvet
sumber
Anda lupa membuang gambar. Tampak prinsip yang sama dengan Bitmap baru (gambar, lebar, tinggi) dengan mode interpolasi yang lebih baik. Saya ingin tahu apa itu Default ? Apakah ini lebih buruk daripada Low?
Sinatr
9

Kode ini sama dengan yang diposkan dari salah satu jawaban di atas .. tetapi akan mengubah piksel transparan menjadi putih alih-alih hitam ... Terima kasih :)

    public Image resizeImage(int newWidth, int newHeight, string stPhotoPath)
    {
        Image imgPhoto = Image.FromFile(stPhotoPath);

        int sourceWidth = imgPhoto.Width;
        int sourceHeight = imgPhoto.Height;

        //Consider vertical pics
        if (sourceWidth < sourceHeight)
        {
            int buff = newWidth;

            newWidth = newHeight;
            newHeight = buff;
        }

        int sourceX = 0, sourceY = 0, destX = 0, destY = 0;
        float nPercent = 0, nPercentW = 0, nPercentH = 0;

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

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


        Bitmap bmPhoto = new Bitmap(newWidth, newHeight,
                      PixelFormat.Format24bppRgb);

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

        Graphics grPhoto = Graphics.FromImage(bmPhoto);
        grPhoto.Clear(Color.White);
        grPhoto.InterpolationMode =
            System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

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

        grPhoto.Dispose();
        imgPhoto.Dispose();

        return bmPhoto;
    }
Rajesh
sumber
7

Dalam aplikasi yang saya buat itu perlu untuk membuat fungsi dengan beberapa opsi. Ini cukup besar, tetapi mengubah ukuran gambar, dapat menjaga rasio aspek dan dapat memotong tepi untuk mengembalikan hanya bagian tengah gambar:

/// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <param name="getCenter">return the center bit of the image</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio, Boolean getCenter)
    {
        int newheigth = heigth;
        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(OriginalFileLocation);

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

        if (keepAspectRatio || getCenter)
        {
            int bmpY = 0;
            double resize = (double)FullsizeImage.Width / (double)width;//get the resize vector
            if (getCenter)
            {
                bmpY = (int)((FullsizeImage.Height - (heigth * resize)) / 2);// gives the Y value of the part that will be cut off, to show only the part in the center
                Rectangle section = new Rectangle(new Point(0, bmpY), new Size(FullsizeImage.Width, (int)(heigth * resize)));// create the section to cut of the original image
                //System.Console.WriteLine("the section that will be cut off: " + section.Size.ToString() + " the Y value is minimized by: " + bmpY);
                Bitmap orImg = new Bitmap((Bitmap)FullsizeImage);//for the correct effect convert image to bitmap.
                FullsizeImage.Dispose();//clear the original image
                using (Bitmap tempImg = new Bitmap(section.Width, section.Height))
                {
                    Graphics cutImg = Graphics.FromImage(tempImg);//              set the file to save the new image to.
                    cutImg.DrawImage(orImg, 0, 0, section, GraphicsUnit.Pixel);// cut the image and save it to tempImg
                    FullsizeImage = tempImg;//save the tempImg as FullsizeImage for resizing later
                    orImg.Dispose();
                    cutImg.Dispose();
                    return FullsizeImage.GetThumbnailImage(width, heigth, null, IntPtr.Zero);
                }
            }
            else newheigth = (int)(FullsizeImage.Height / resize);//  set the new heigth of the current image
        }//return the image resized to the given heigth and width
        return FullsizeImage.GetThumbnailImage(width, newheigth, null, IntPtr.Zero);
    }

Untuk memudahkan mengakses fungsi, Anda dapat menambahkan beberapa fungsi kelebihan beban:

/// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width)
    {
        return resizeImageFromFile(OriginalFileLocation, heigth, width, false, false);
    }

    /// <summary>
    /// Resize image with a directory as source
    /// </summary>
    /// <param name="OriginalFileLocation">Image location</param>
    /// <param name="heigth">new height</param>
    /// <param name="width">new width</param>
    /// <param name="keepAspectRatio">keep the aspect ratio</param>
    /// <returns>image with new dimentions</returns>
    public Image resizeImageFromFile(String OriginalFileLocation, int heigth, int width, Boolean keepAspectRatio)
    {
        return resizeImageFromFile(OriginalFileLocation, heigth, width, keepAspectRatio, false);
    }

Sekarang adalah dua boolean terakhir opsional untuk ditetapkan. Panggil fungsi seperti ini:

System.Drawing.Image ResizedImage = resizeImageFromFile(imageLocation, 800, 400, true, true);
Quispie
sumber
6
public string CreateThumbnail(int maxWidth, int maxHeight, string path)
{

    var image = System.Drawing.Image.FromFile(path);
    var ratioX = (double)maxWidth / image.Width;
    var ratioY = (double)maxHeight / image.Height;
    var ratio = Math.Min(ratioX, ratioY);
    var newWidth = (int)(image.Width * ratio);
    var newHeight = (int)(image.Height * ratio);
    var newImage = new Bitmap(newWidth, newHeight);
    Graphics thumbGraph = Graphics.FromImage(newImage);

    thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
    thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
    //thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

    thumbGraph.DrawImage(image, 0, 0, newWidth, newHeight);
    image.Dispose();

    string fileRelativePath = "newsizeimages/" + maxWidth + Path.GetFileName(path);
    newImage.Save(Server.MapPath(fileRelativePath), newImage.RawFormat);
    return fileRelativePath;
}

Klik di sini http://bhupendrasinghsaini.blogspot.in/2014/07/resize-image-in-c.html

bhupendra singh
sumber
6

Ini adalah kode yang saya kerjakan untuk persyaratan tertentu yaitu: tujuan selalu dalam rasio lanskap. Ini akan memberi Anda awal yang baik.

public Image ResizeImage(Image source, RectangleF destinationBounds)
{
    RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height);
    RectangleF scaleBounds = new RectangleF();

    Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height);
    Graphics graph = Graphics.FromImage(destinationImage);
    graph.InterpolationMode =
        System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

    // Fill with background color
    graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds);

    float resizeRatio, sourceRatio;
    float scaleWidth, scaleHeight;

    sourceRatio = (float)source.Width / (float)source.Height;

    if (sourceRatio >= 1.0f)
    {
        //landscape
        resizeRatio = destinationBounds.Width / sourceBounds.Width;
        scaleWidth = destinationBounds.Width;
        scaleHeight = sourceBounds.Height * resizeRatio;
        float trimValue = destinationBounds.Height - scaleHeight;
        graph.DrawImage(source, 0, (trimValue / 2), destinationBounds.Width, scaleHeight);
    }
    else
    {
        //portrait
        resizeRatio = destinationBounds.Height/sourceBounds.Height;
        scaleWidth = sourceBounds.Width * resizeRatio;
        scaleHeight = destinationBounds.Height;
        float trimValue = destinationBounds.Width - scaleWidth;
        graph.DrawImage(source, (trimValue / 2), 0, scaleWidth, destinationBounds.Height);
    }

    return destinationImage;

}
Leslie Marshall
sumber
Luar Biasa !!! Saya mengalami masalah dalam gambar potret dan setelah mencoba banyak solusi yang dicari di web, ini HANYA yang SEMPURNA! TERIMA KASIH BANYAK!
Fábio
3

Jika Anda bekerja dengan BitmapSource:

var resizedBitmap = new TransformedBitmap(
    bitmapSource,
    new ScaleTransform(scaleX, scaleY));

Jika Anda ingin kontrol yang lebih baik atas kualitas, jalankan ini terlebih dahulu:

RenderOptions.SetBitmapScalingMode(
    bitmapSource,
    BitmapScalingMode.HighQuality);

(Default adalah BitmapScalingMode.Linearyang setara dengan BitmapScalingMode.LowQuality.)

Mateen Ulhaq
sumber
3

Saya menggunakan ImageProcessorCore, sebagian besar karena berfungsi. Net Core.

Dan ia memiliki lebih banyak opsi seperti mengonversi jenis, memotong gambar, dan lainnya

http://imageprocessor.org/imageprocessor/

topolm
sumber
1
Saya melihat dan ini tidak mendukung .NET Core. Itu dibangun melawan kerangka penuh.
chrisdrobison
1

Ubah ukuran dan simpan gambar agar pas dengan lebar dan tinggi seperti kanvas yang menjaga gambar tetap proporsional

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

namespace Infra.Files
{
    public static class GenerateThumb
    {
        /// <summary>
        /// Resize and save an image to fit under width and height like a canvas keeping things proportional
        /// </summary>
        /// <param name="originalImagePath"></param>
        /// <param name="thumbImagePath"></param>
        /// <param name="newWidth"></param>
        /// <param name="newHeight"></param>
        public static void GenerateThumbImage(string originalImagePath, string thumbImagePath, int newWidth, int newHeight)
        {
            Bitmap srcBmp = new Bitmap(originalImagePath);
            float ratio = 1;
            float minSize = Math.Min(newHeight, newHeight);

            if (srcBmp.Width > srcBmp.Height)
            {
                ratio = minSize / (float)srcBmp.Width;
            }
            else
            {
                ratio = minSize / (float)srcBmp.Height;
            }

            SizeF newSize = new SizeF(srcBmp.Width * ratio, srcBmp.Height * ratio);
            Bitmap target = new Bitmap((int)newSize.Width, (int)newSize.Height);

            using (Graphics graphics = Graphics.FromImage(target))
            {
                graphics.CompositingQuality = CompositingQuality.HighSpeed;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.CompositingMode = CompositingMode.SourceCopy;
                graphics.DrawImage(srcBmp, 0, 0, newSize.Width, newSize.Height);

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    target.Save(thumbImagePath);
                }
            }
        }
    }
}
Andrew Paes
sumber
1

Gunakan fungsi di bawah ini dengan contoh di bawah ini untuk mengubah ukuran gambar:

//Example : 
System.Net.Mime.MediaTypeNames.Image newImage = System.Net.Mime.MediaTypeNames.Image.FromFile("SampImag.jpg");
System.Net.Mime.MediaTypeNames.Image temImag = FormatImage(newImage, 100, 100);

//image size modification unction   
public static System.Net.Mime.MediaTypeNames.Image FormatImage(System.Net.Mime.MediaTypeNames.Image img, int outputWidth, int outputHeight)
{

    Bitmap outputImage = null;
    Graphics graphics = null;
    try
    {
         outputImage = new Bitmap(outputWidth, outputHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
         graphics = Graphics.FromImage(outputImage);
         graphics.DrawImage(img, new Rectangle(0, 0, outputWidth, outputHeight),
         new Rectangle(0, 0, img.Width, img.Height), GraphicsUnit.Pixel);

         return outputImage;
     }
     catch (Exception ex)
     {
           return img;
     }
}
Prasad KM
sumber
2
Harap pertimbangkan untuk menjelaskan dalam jawaban Anda di atas cara menggunakan kode ini, apa yang dilakukan kode, dan bagaimana memecahkan masalah dalam pertanyaan awal.
Tim Visée
Saya telah menambahkan use case juga. Gunakan fungsi di atas dengan contoh di bawah ini. Gambar newImage = Image.FromFile ("SampImag.jpg"); Gambar temImag = FormatImage (newImage, 100, 100);
Prasad KM
0

Catatan: ini tidak akan bekerja dengan ASP.Net Core karena WebImage tergantung pada System.Web, tetapi pada versi ASP.Net sebelumnya saya menggunakan potongan ini berkali-kali dan berguna.

String ThumbfullPath = Path.GetFileNameWithoutExtension(file.FileName) + "80x80.jpg";
var ThumbfullPath2 = Path.Combine(ThumbfullPath, fileThumb);
using (MemoryStream stream = new MemoryStream(System.IO.File.ReadAllBytes(fullPath)))
{
      var thumbnail = new WebImage(stream).Resize(80, 80);
      thumbnail.Save(ThumbfullPath2, "jpg");
}
JoshYates1980
sumber