views:

1652

answers:

3

I am trying to resize an image as follows. I return the resized image into byte[] so that I can store it in database. The transparency of png image is lost. Please help to make this better.

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;
  }
}
A: 

Have you tried using the .MakeTransparent() call on your bitmap object?

Ash
Yes. Even that didnt work.
+5  A: 

Your code doesn't do quite what you think that it does...

You use the GetThumbnailImage to resize the image, then you draw the thumbnail image into itself which is rather pointless. You probably lose the transparency in the first step.

Create a blank bitmap instead, and resize the source image by drawing it on the blank bitmap.

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 removed some parameters that were never used for anything that had anything to do with the result, like the imageLen parameter that was only used to create a byte array that was never used.)

Guffa
This solution also doesnt give me a transparent image.
I tried it out with both PNG-8 and PNG-24 images, and it does preserve the transparency. Could you post the image that you are trying to resize?
Guffa
Well if I look at test.png it does preserve the transparency. But If I store the byte[] in database and re-access it, the try to load that image on my web page then the background is displayed as grey. But this wasnt the case when I was loading the image directly into the database without reszing.
I tried to load test.png without resizing into the database and displaying test.png, I found that the transparency was lost. Although when I open up test.png in Windows Picture viewer it seems to have transparency.
when I open test.png in paintbrush the image shows up with black background and not as transparent. Therefore, I am pretty certain that resizing is destroying the transparency of the image.
What browser are you using? IE6 does not support transparency for PNG-24 images. Paint doesn't support transparency at all.
Guffa
Yes it is problem with IE 6. http://support.microsoft.com/kb/294714
A: 

May be you should do something like this coz this thing worked for me:

    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);
    }
Kishan Hathiwala