368 Stimmen

Wie man die Größe eines Bildes ändert C#

として Size , Width y Height son Get() Eigenschaften von System.Drawing.Image ;
Wie kann ich die Größe eines Image-Objekts zur Laufzeit in C# ändern?

Im Moment erstelle ich gerade eine neue Image verwenden:

// objImage is the original Image
Bitmap objBitmap = new Bitmap(objImage, new Size(227, 171));

632voto

mpen Punkte 253762

Damit wird eine qualitativ hochwertige Größenänderung durchgeführt:

/// <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) verhindert Geisterbilder an den Bildrändern - bei einer naiven Größenanpassung werden transparente Pixel jenseits der Bildgrenzen abgetastet, aber durch Spiegelung des Bildes können wir eine bessere Abtastung erreichen (diese Einstellung ist sehr auffällig)
  • destImage.SetResolution Behält die DPI unabhängig von der Größe bei - kann die Qualität beim Verkleinern der Bildgröße oder beim Drucken erhöhen
  • Compositing steuert, wie die Pixel mit dem Hintergrund überblendet werden - wird möglicherweise nicht benötigt, da wir nur eine Sache zeichnen.
    • graphics.CompositingMode bestimmt, ob die Pixel eines Quellbildes die Hintergrundpixel überschreiben oder mit ihnen kombiniert werden. SourceCopy legt fest, dass eine Farbe, wenn sie gerendert wird, die Hintergrundfarbe überschreibt.
    • graphics.CompositingQuality bestimmt die Rendering-Qualitätsstufe von überlagerten Bildern.
  • graphics.InterpolationMode bestimmt, wie Zwischenwerte zwischen zwei Endpunkten berechnet werden
  • graphics.SmoothingMode gibt an, ob Linien, Kurven und die Ränder gefüllter Flächen geglättet werden sollen (auch Antialiasing genannt) -- funktioniert wahrscheinlich nur bei Vektoren
  • graphics.PixelOffsetMode beeinflusst die Rendering-Qualität beim Zeichnen des neuen Bildes

Die Beibehaltung des Seitenverhältnisses ist eine Übung für den Leser (ich glaube nicht, dass es die Aufgabe dieser Funktion ist, das für Sie zu tun).

También, Dies ist ein guter Artikel in dem einige der Fallstricke bei der Größenänderung von Bildern beschrieben werden. Die obige Funktion deckt die meisten von ihnen ab, aber Sie müssen sich immer noch Gedanken machen über speichern .

177voto

Matt Punkte 1673

Nicht sicher, was ist so schwierig über diese, tun, was Sie taten, verwenden Sie den überladenen Bitmap-Konstruktor, um ein Bild in neuer Größe zu erstellen, das einzige, was Sie fehlte, war ein Cast zurück zu den Image-Datentyp:

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

yourImage = resizeImage(yourImage, new Size(50,50));

52voto

Vinzz Punkte 3828

において diese Frage werden Sie einige Antworten erhalten, auch meine:

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

36voto

kleisauke Punkte 466

Sie könnten versuchen net-vips , die C#-Anbindung für libvips . Es handelt sich um eine "lazy", streaming, bedarfsgesteuerte Bildverarbeitungsbibliothek, die Operationen wie diese durchführen kann, ohne dass das gesamte Bild geladen werden muss.

Zum Beispiel verfügt es über einen praktischen Thumbnailer für Bilder:

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

Sie unterstützt auch den intelligenten Bildzuschnitt, der den wichtigsten Teil des Bildes bestimmt und ihn beim Zuschneiden des Bildes im Fokus behält. Zum Beispiel:

using Image image = Image.Thumbnail("owl.jpg", 128, crop: Enums.Interesting.Attention);
image.WriteToFile("tn_owl.jpg");

Wo owl.jpg ist eine außermittige Zusammensetzung:

Owl

Ergibt dieses Ergebnis:

Owl smart crop

Zuerst wird das Bild verkleinert, um die vertikale Achse auf 128 Pixel zu bringen, dann wird es auf 128 Pixel Breite beschnitten, indem die attention Strategie. Bei dieser Strategie wird das Bild nach Merkmalen durchsucht, die einem Menschen ins Auge fallen könnten, siehe Smartcrop() für Details.

30voto

Lino Silva Punkte 461

Warum nicht die System.Drawing.Image.GetThumbnailImage Methode?

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

Beispiel:

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X