2009-04-15 17 views
9

Estoy tratando de cambiar el tamaño de una imagen de la siguiente manera. Devuelvo la imagen redimensionada al byte[] para poder almacenarla en la base de datos. La transparencia de la imagen png se pierde. Por favor ayuda a hacer esto mejor.¿Por qué el cambio de tamaño de una imagen png pierde transparencia?

private byte[] GetThumbNail(string imageFile, Stream imageStream, 
    int imageLen) 
{ 
    try 
    { 
    Image.GetThumbnailImageAbort imageCallBack = 
     new Image.GetThumbnailImageAbort(ThumbnailCallback); 
    Bitmap getBitmap = new Bitmap(imageFile); 
    byte[] returnByte = new byte[imageLen]; 
    Image getThumbnail = getBitmap.GetThumbnailImage(160, 59, 
     imageCallBack, IntPtr.Zero); 
    using (Graphics g = Graphics.FromImage(getThumbnail)) 
    { 
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     g.InterpolationMode = 
     System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     g.DrawImage(getThumbnail, 0, 0, 160, 59); 
    } 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     getThumbnail.Save(ms, ImageFormat.Png); 
     getThumbnail.Save("test.png", ImageFormat.Png); 
     returnByte = ms.ToArray(); 
    } 
    return returnByte; 
    } 
    catch (Exception) 
    { 
    throw; 
    } 
} 

Respuesta

7

Intente utilizar la llamada .MakeTransparent() en su objeto de mapa de bits.

+0

Sí. Incluso eso no funcionó. –

+0

¡Sí! ¡Funciona! ¡Me salvas! Es importante utilizar .MakeTransparent() en cada paso del cambio de tamaño de la imagen o recortar. Después de crear una nueva imagen(). ¡Gracias! –

+0

¿Qué objeto tiene esta llamada MakeTransparent? –

23

Su código no hace exactamente lo que usted piensa que lo hace ...

Se utiliza el GetThumbnailImage para cambiar el tamaño de la imagen, a continuación, se dibuja la imagen en miniatura en sí mismo, que es bastante inútil. Probablemente pierdas la transparencia en el primer paso.

Cree en su lugar un mapa de bits en blanco y redimensione la imagen de origen dibujándola en el mapa de bits en blanco.

private byte[] GetThumbNail(string imageFile) { 
    try { 
    byte[] result; 
    using (Image thumbnail = new Bitmap(160, 59)) { 
     using (Bitmap source = new Bitmap(imageFile)) { 
     using (Graphics g = Graphics.FromImage(thumbnail)) { 
      g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
      g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
      g.DrawImage(source, 0, 0, 160, 59); 
     } 
     } 
     using (MemoryStream ms = new MemoryStream()) { 
     thumbnail.Save(ms, ImageFormat.Png); 
     thumbnail.Save("test.png", ImageFormat.Png); 
     result = ms.ToArray(); 
     } 
    } 
    return result; 
    } catch (Exception) { 
    throw; 
    } 
} 

(I eliminado algunos parámetros que no fueron utilizados para cualquier cosa que tuviera algo que ver con el resultado, al igual que el parámetro imageLen que sólo se utilizó para crear una matriz de bytes que nunca fue utilizado.)

+0

Esta solución tampoco me da una imagen transparente. –

+0

Lo probé con imágenes PNG-8 y PNG-24, y conserva la transparencia. ¿Podría publicar la imagen que está tratando de cambiar el tamaño? – Guffa

+0

Bueno, si miro en test.png, conserva la transparencia. Pero si guardo el byte [] en la base de datos y lo vuelvo a acceder, intento cargar esa imagen en mi página web y luego el fondo se muestra en gris. Pero este no era el caso cuando estaba cargando la imagen directamente en la base de datos sin reszing. –

2

puede ser que usted debe hacer algo como esto porque esto funcionó para mí:

String path = context.Server.MapPath("/images"); 
if (!path.EndsWith("\\")) 
    path += "\\"; 
path += "none.png"; 

Image img = CreateThumbnail(Image.FromFile(path)); 

MemoryStream ms = new MemoryStream(); 
img.Save(ms, ImageFormat.Png); 
ms.WriteTo(context.Response.OutputStream); 

private System.Drawing.Image CreateThumbnail(System.Drawing.Image i) 
{ 
    int dWidth = i.Width; 
    int dHeight = i.Height; 
    int dMaxSize = 150; 

    if (dWidth > dMaxSize) 
    { 
     dHeight = (dHeight * dMaxSize)/dWidth; 
     dWidth = dMaxSize; 
    } 
    if (dHeight > dMaxSize) 
    { 
     dWidth = (dWidth * dMaxSize)/dHeight; 
     dHeight = dMaxSize; 
    } 
    return i.GetThumbnailImage(dWidth, dHeight, delegate() { return false; }, IntPtr.Zero); 
} 
Cuestiones relacionadas