web-dev-qa-db-fra.com

Mise à l'échelle d'un System.Drawing.Bitmap à une taille donnée tout en maintenant les proportions

Je veux escalader un System.Drawing.Bitmap au moins inférieure à certaines largeur et hauteur fixes. Cela permet de générer des vignettes pour une galerie d'images sur un site Web. Je souhaite donc que les proportions soient les mêmes.

J'ai quelques solutions, mais aucune ne semble vraiment faire ce dont j'ai besoin; ils tournent autour de la mise à l'échelle en gardant la largeur ou la hauteur identiques sans modifier les deux.

Un exemple:

Si j'ai une image 4272 x 2848 et que je souhaite l'adapter à une taille de 1024 x 768, l'image résultante doit être de 1024 x 683 et complétée (avec une bordure noire) à 1024 x 768.

Comment puis-je faire cela avec des images plus grandes que la taille requise et plus petites que la taille requise ainsi que des images de remplissage qui ne sortent pas à la taille exacte dont j'ai besoin une fois redimensionné?

50
Michael J. Gray

Paramètres cibles:

float width = 1024;
float height = 768;
var brush = new SolidBrush(Color.Black);

Votre fichier d'origine:

var image = new Bitmap(file);

Dimensionnement de la cible (facteur d'échelle):

float scale = Math.Min(width / image.Width, height / image.Height);

Le redimensionnement, y compris le brossage en premier:

var bmp = new Bitmap((int)width, (int)height);
var graph = Graphics.FromImage(bmp);

// uncomment for higher quality output
//graph.InterpolationMode = InterpolationMode.High;
//graph.CompositingQuality = CompositingQuality.HighQuality;
//graph.SmoothingMode = SmoothingMode.AntiAlias;

var scaleWidth = (int)(image.Width * scale);
var scaleHeight = (int)(image.Height * scale);

graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
graph.DrawImage(image, ((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight);

Et n'oubliez pas de faire une bmp.Save(filename) pour sauvegarder le fichier résultant.

53
yamen

Le constructeur bitmap a un redimensionnement intégré.

Bitmap original = (Bitmap)Image.FromFile("DSC_0002.jpg");
Bitmap resized = new Bitmap(original,new Size(original.Width/4,original.Height/4));
resized.Save("DSC_0002_thumb.jpg");

http://msdn.Microsoft.com/en-us/library/0wh0045z.aspx

Si vous voulez contrôler les modes d'interpolation, voyez this post .

136
WHol

Juste pour ajouter à la réponse de yamen qui est le préfet pour les images mais pas tellement pour le texte. Si vous essayez d’utiliser ceci pour mettre à l’échelle le texte, comme dans un document Word (qui est dans ce cas en octets à partir de Word interop), vous devrez apporter quelques modifications ou vous obtiendrez des barres géantes sur le côté. Peut-être pas parfait mais fonctionne pour moi!

using (MemoryStream ms = new MemoryStream(wordBytes))
                {
                    float width = 3840;
                    float height = 2160;

                    var brush = new SolidBrush(Color.White);
                    var rawImage = Image.FromStream(ms);
                    float scale = Math.Min(width / rawImage.Width, height / rawImage.Height);
                    var scaleWidth = (int)(rawImage.Width * scale);
                    var scaleHeight = (int)(rawImage.Height * scale);
                    var scaledBitmap = new Bitmap(scaleWidth, scaleHeight);
                    Graphics graph = Graphics.FromImage(scaledBitmap);
                    graph.InterpolationMode = InterpolationMode.High;
                    graph.CompositingQuality = CompositingQuality.HighQuality;
                    graph.SmoothingMode = SmoothingMode.AntiAlias;
                    graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
                    graph.DrawImage(rawImage, new Rectangle(0, 0 , scaleWidth, scaleHeight));
                    scaledBitmap.Save(fileName, ImageFormat.Png);
                    return scaledBitmap;
                }
2
Trent