Escalando un Sistema.Dibujo.Mapa de bits a un tamaño dado mientras se mantiene la relación de aspecto


Quiero escalar un System.Drawing.Bitmap a por lo menos menos que algún ancho y altura fijos. Esto es para generar miniaturas para una galería de imágenes en un sitio web, por lo que quiero mantener la relación de aspecto igual.

Tengo algunos a través de bastantes soluciones, pero ninguno parece realmente hacer lo que necesito; giran en torno a la escala basada en mantener el ancho o la altura de la misma, pero no cambiar ambos.

Un ejemplo:

Si tengo una imagen de 4272 por 2848 y quiero escalarla a un tamaño de 1024 por 768, entonces la imagen resultante debe ser 1024 por 683 y acolchada (con un borde negro) a 1024 por 768.

¿Cómo puedo hacer esto con imágenes más grandes que el tamaño requerido y más pequeñas que el tamaño requerido y también pad imágenes que no salen al tamaño exacto que necesito una vez escalado?

Author: Michael J. Gray, 2012-05-04

3 answers

Parámetros de destino:

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

Su archivo original:

var image = new Bitmap(file);

Dimensionamiento objetivo (factor de escala):

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

El cambio de tamaño incluyendo el lienzo de cepillado primero:

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

Y no olvides hacer un bmp.Save(filename) para guardar el archivo resultante.

 45
Author: yamen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-28 20:24:21

El constructor de mapa de bits tiene incorporado el redimensionamiento.

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 quieres control sobre los modos de interpolación ver este post.

 121
Author: WHol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-06 13:23:30

Solo para añadir a la respuesta de yamen que es perfecta para imágenes pero no tanto para texto. Si está tratando de usar esto para escalar el texto.. como decir un documento de Word (que es en este caso en bytes de word interop) tendrá que hacer algunas modificaciones o obtendrá barras gigantes en el lado. Puede que no sea perfecto, pero funciona para mí!

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
Author: Trent Stollery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-20 23:33:37