C# 为什么调整 png 图像大小会失去透明度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/753968/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:52:32  来源:igfitidea点击:

Why does resizing a png image lose transparency?

c#imageresizepngtransparency

提问by

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.

我正在尝试按如下方式调整图像大小。我将调整后的图像返回,byte[]以便我可以将其存储在数据库中。png 图像的透明度丢失。请帮助使这更好。

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

回答by Ash

Try using the .MakeTransparent()call on your bitmap object.

尝试.MakeTransparent()在位图对象上使用调用。

回答by Guffa

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.

您使用 GetThumbnailImage 调整图像大小,然后将缩略图图像绘制到自身中,这是毫无意义的。您可能在第一步中失去了透明度。

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

(我删除了一些从未用于任何与结果有关的参数,例如仅用于创建从未使用过的字节数组的 imageLen 参数。)

回答by Kishan Hathiwala

May be you should do something like this because 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);
}