Ich versuche, die Größe eines Bildes zu ändern, während das Seitenverhältnis zum Originalbild beibehalten wird, damit das neue Bild nicht gequetscht aussieht.
z.B:
Konvertieren Sie ein 150 * 100-Bild in ein 150 * 150-Bild.
Die zusätzlichen 50 Pixel der Höhe müssen mit einer weißen Hintergrundfarbe aufgefüllt werden.
Dies ist der aktuelle Code, den ich verwende.
Es eignet sich gut zum Ändern der Größe, aber durch Ändern des Seitenverhältnisses des Originalbilds wird das neue Bild gequetscht.
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);
}
BEARBEITEN: Ich möchte, dass das Bild aufgefüllt statt beschnitten wird
Path.Combine(path, originalFileName)
beim Laden des Originalbildes zu verwenden. Gleiches gilt für das Speichern der Miniaturansicht am Ende.Ich habe herausgefunden, wie ich die Größe des Bildes ändern UND es auffüllen kann, indem ich aus diesem CodeProject-Artikel gelernt habe .
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; }
quelle
Ich benutze die folgende Methode, um die gewünschte Bildgröße zu berechnen:
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)); }
Dies stellt das Problem des Seitenverhältnisses und der Abmessungen in eine separate Methode.
quelle
enlarge
?Um ein schnelleres Ergebnis zu erzielen, finden Sie die Funktion, die die Größe erhält, in
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));
Dient
Linq
zum Minimieren von Variablen und Neuberechnungen sowie für unnötigeif/else
Anweisungenquelle
If/else
wäre besser gewesen als eine ListeMath.Min
zuzuweisen, war auch eine OptionWenn Sie es nur auf Seitenverhältnisse und Größen verallgemeinern, können Sie Bilder außerhalb dieser Funktion erstellen
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; }
quelle
RectangleF
.Ich werde auch hier meinen Code hinzufügen. Mit diesem Code können Sie die Größe eines Bildes mit oder ohne erzwungenes Seitenverhältnis ändern oder die Größe durch Auffüllen ändern. Dies ist eine modifizierte Version von Egrunins Code.
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); } } }
quelle
Hier ist eine weniger spezifische Erweiterungsmethode, die mit Image funktioniert, anstatt das Laden und Speichern für Sie durchzuführen. Außerdem können Sie die Interpolationsmethode angeben und Kanten korrekt rendern, wenn Sie die NearestNeighbour-Interpolation verwenden.
Das Bild wird innerhalb der Grenzen des von Ihnen angegebenen Bereichs gerendert, sodass Sie immer Ihre Ausgabebreite und -höhe kennen. z.B:
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; } } }
quelle
Hinweis: Dieser Code ändert die Größe und entfernt alles außerhalb des Seitenverhältnisses, anstatt es aufzufüllen.
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; } } }
quelle
// 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); }
quelle
Behalten Sie die Aspekt-Ration bei und entfernen Sie Briefkasten und Säulenbox.
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; }
quelle
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); } }
quelle
Ich habe das gerade geschrieben, weil keine der Antworten hier schon einfach genug war. Sie können die fest codierte 128 gegen eine beliebige Größe austauschen oder sie auf der Größe des Originalbilds basieren. Ich wollte das Bild nur in ein 128x128-Bild skalieren, das Seitenverhältnis beibehalten und das Ergebnis im neuen Bild zentrieren.
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; }
quelle
Ich habe eine Erweiterungsmethode erstellt, die viel einfacher ist als die Antworten, die veröffentlicht werden. und das Seitenverhältnis wird angewendet, ohne das Bild zuzuschneiden.
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); }
Anwendungsbeispiel:
using (var img = Image.FromFile(pathToOriginalImage)) { using (var thumbnail = img.Resize(60, 60)){ // Here you can do whatever you need to do with thumnail } }
quelle