C# 高质量双三次插值在调整大小时添加黑色背景

C# 高质量双三次插值在调整大小时添加黑色背景,c#,image-processing,background,transparency,gdi+,C#,Image Processing,Background,Transparency,Gdi+,我正在实现图像缩放功能。当我使用HighQualityBicubic插值模式(从质量角度来看这是首选)时,我在调整大小的图像上得到黑色背景(仅在源图像的矩形中。在目标矩形的填充区域中,它仍然是透明的)。 输入图像为透明背景的bmp。 输出也是bmp 32 bpp。 有趣的是,当我将InterpolationMode更改为NearestNeighbor时,一些输入图像的背景在调整大小后保持为透明,而另一个输入则没有帮助。 我做错了什么 public Bitmap DrawScaledImage(I

我正在实现图像缩放功能。当我使用HighQualityBicubic插值模式(从质量角度来看这是首选)时,我在调整大小的图像上得到黑色背景(仅在源图像的矩形中。在目标矩形的填充区域中,它仍然是透明的)。 输入图像为透明背景的bmp。 输出也是bmp 32 bpp。 有趣的是,当我将InterpolationMode更改为NearestNeighbor时,一些输入图像的背景在调整大小后保持为透明,而另一个输入则没有帮助。 我做错了什么

public Bitmap DrawScaledImage(Image img, int width, int height, int scaledWidth, int scaledHeight)
    {
        var resultImg = new Bitmap(width, height, PixelFormat.Format32bppArgb);
        resultImg.SetResolution(img.HorizontalResolution, img.VerticalResolution);
        using (Graphics grPhoto = Graphics.FromImage(resultImg))
        {
            grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
            grPhoto.DrawImage(img,
                new Rectangle(0, 0, scaledWidth, scaledHeight), //0;0 - image is drawn in left top corner
                new Rectangle(0, 0, img.Width, img.Height),
                GraphicsUnit.Pixel);
        }
        return resultImg;
    }

更新 发现有趣的事情: 我在源图像中随机选取了透明像素,并在调试中获取了它的ARGB:它是ARGB=(255,0,0),非常清晰 然后我选择了相同的像素,在缩放后目标图像中是透明的,它仍然是ARGB=(255,0,0,0),但在Paint.Net中它显示为黑色。 然后,我从目标图像中随机选取了另一个像素,它在Paint.Net中显示为透明,其ARGB模式为ARGB=(0,0,0,0)-什么

所以也许是个愚蠢的问题——为什么第一个pic透明像素是[255;0;0;0],而第二个[255;0;0;0]意味着黑色和透明是[0;0;0]。 看起来好像有什么东西沉下去了。在缩放后,阿尔法通道将其含义从255透明变为255不透明。有什么想法吗?

所以我发现原因是在使用
InterpolationMode=InterpolationMode.HighQualityBicubic
调整大小后,以BMP格式保存文件时出现了一些错误行为。以下是复制的案例: 1.如果我使用pixel format
PixelFormat.Format32bppArgb
创建全新图像,使用像素进行一些程序操作(例如绘制一些线条)并另存为bmp-完全没有问题,透明度在paint.Net中保存并可见。 2.如果我已经用透明的方式打开现有的bmp图像,用
Graphics.DrawImage
方法将其放大/缩小,在调试中效果似乎都很好。透明像素的Alpha=0。然后我将该图像保存为bmp。然后在类似于
Image.FromFile(“resized.bmp”)
的代码中再次打开它,它的像素格式与保存前不同:它现在是
Format32bppRgb
,但保存的图像有
Format32bppArgb
。在打开的图像上,透明像素现在的Alpha=255。这就是为什么在Paint.Net中打开时,我在调整大小后看到黑色而不是透明的原因

我找到了两种在调整大小后保持透明度的变通方法: 1.将
InterpolationMode
InterpolationMode.HighQualityBicubic
更改为
InterpolationMode.nearestnear
。这解决了透明度问题,但由于低质量的方法而无法接受。
2.将调整大小的图像另存为.png。这将保存正确的Alpha值,重新打开图像将使其保持静止。因此,我的解决方案是拒绝使用BMP文件格式。

在绘制调整大小的版本之前,您可能希望将新位图的背景设置为透明:
grPhoto.Clear(Color.transparent)
@TaW谢谢您的提示。不幸的是,它不会改变结果图像中的任何内容。我已经试过了,只是再次检查。还尝试了
resultImg.MakeTransparent()与其说是提示,不如说是需求。你能发布一个原始图像和(错误的)结果吗?或者你发布的图像就是这样吗?(不,第一张图像有一个白色中心)-还要注意,许多应用程序无法正确显示透明度,例如IrfanView会将其显示为黑色…(但是.Net Paint应该可以正常工作)@TaW这里的源代码和结果是:您可以尝试使用我上面的代码调整源代码的大小-我猜您将获得与黑色背景相同的结果,正如我所提到的-如果您设置
grPhoto.InterpolationMode=InterpolationMode.NearestNeighbor它将在透明背景下调整大小。我猜是这样的(但到目前为止还没有时间研究)-即使是Photoshop CS2也不理解“新”32位BMP格式,那么为什么GDI+?-)-(仍然有人想知道插值模式与它有什么关系???@TaW对。我在这个话题上不是很强,所以我将把插值留给其他人:)无论如何,谢谢你的支持。