2012-05-04 11 views
36

Desidero ridimensionare uno System.Drawing.Bitmap almeno a una larghezza e un'altezza fisse. Questo è quello di generare miniature per una galleria di immagini su un sito Web, quindi voglio mantenere le proporzioni allo stesso modo.Ridimensionamento di un System.Drawing.Bitmap in base a una determinata dimensione mantenendo le proporzioni

Ho alcune soluzioni diverse ma nessuna sembra davvero fare ciò di cui ho bisogno; ruotano attorno al ridimensionamento basato sul mantenere la larghezza o l'altezza lo stesso, ma non cambiano entrambi.

Un esempio:

Se ho un 4272 per immagine 2848 e voglio scalare a una dimensione di 1024 x 768, quindi l'immagine risultante dovrebbe essere 1024 da 683 e imbottita (con un bordo nero) a 1024 da 768.

Come posso fare questo con immagini più grandi della dimensione richiesta e più piccole delle dimensioni richieste e anche immagini di pad che non escono alla dimensione esatta che mi serve una volta ridimensionata?

+0

Perché non puoi semplicemente fare i calcoli per calcolare l'altra dimensione? –

+0

@CodyGray Quale "altra" dimensione esattamente? È un'immagine bidimensionale che deve essere ridimensionata mantenendo le sue proporzioni. Ho provato solo a prendere le proporzioni e a capire un denominatore comune per la larghezza e l'altezza che è vicino alla dimensione del bersaglio, e non ha mai funzionato correttamente. –

risposta

38

parametri Target:

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

Il file originale:

var image = new Bitmap(file); 

Target (fattore di scala) dimensionamento:

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

Il ridimensionamento tra cui tela spazzolatura prima:

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, new Rectangle(((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight)); 

E non dimenticare di fare un bmp.Save(filename) per salvare il file risultante.

+1

Questo crea un'immagine nera piena. –

+0

Funziona perfettamente per me, senza necessità di downvotare a meno che tu non sia sicuro di aver trovato il problema. Rimuovi la linea 'FillRectangle' e vedi cosa ottieni. Appena testato di nuovo e funziona bene. Sono su .NET 4.0 se questo fa la differenza. – yamen

+0

Non funziona se le dimensioni di destinazione sono entrambe inferiori alle dimensioni dell'immagine. 'scale' diventa 0.0. Inoltre non conserverà affatto il rapporto di aspetto, da quello che posso dire. –

99

Il costruttore bitmap ha costruito nel ridimensionamento.

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

Se si vuole il controllo sulla modalità di interpolazione vedere this post.

+2

Grazie. Questo ha aiutato molto. So che questa è una risposta un po 'vecchia, ma c'è una ragione per cui la mia nuova immagine è sfocata? Devo impostare qualsiasi modalità di interpolazione? – theGreenCabbage

+1

Non è sufficiente disegnare la bitmap originale all'interno di una nuova bitmap più piccola? Una parte dell'immagine dovrebbe essere tagliata. – DerpyNerd

+2

* Non è sufficiente disegnare la bitmap originale all'interno di una nuova bitmap più piccola? * Il collegamento a TFM è proprio qui: * Inizializza una nuova istanza della classe Bitmap dall'immagine esistente specificata, ** ridimensionata alla dimensione specificata ** . * –