`GetThumbnailAsync`透明度问题

时间:2017-05-01 16:35:35

标签: windows-runtime uwp png transparency

我知道有很多关于“当我在UWP上创建缩略图时,zomg png透明度消失了”的线索,但这比这更微妙。

我意识到GetThumbnailAsync的输出是位图,通常没有透明度支持。我知道默认情况下,用于在UWP下转换为位图的透明图像的背景颜色是应用程序的背景颜色(这是一个完全不同的问题),但我发现当用图标调用GetThumbnailAsync时现有的32位透明度,这种透明度得以保留。

但是,当针对具有透明度的PNG调用GetThumbnailAsync时,背景将被强制为黑色。当PNG中唯一不透明的颜色是黑色时,这很糟糕,因为你最终会得到一个全黑的斑点。

Heres'截图,其中呈现了2个Image元素,每个元素的来源都是对GetThumbnailAsync()的调用。第一个图标是针对具有32位图标w /透明度的exe调用的,第二个是针对具有透明度的32位PNG:

GetThumbnailAsync results, exe vs png

这表明GetThumbnailAsync()创建的结果位图图像实际上支持透明度,并且背景颜色实际上可以是“透明”而不是“应用程序颜色”。但由于某种原因,PNG缩略图总是失去透明度。有没有解决这个问题?

1 个答案:

答案 0 :(得分:1)

我认为这归结为Windows 10中的“错误”,似乎透明度数据通常会丢失。以下是我在Windows资源管理器中拖动源文件时发生的情况,这是一个PNG w / transparency和仅黑色前景:

all black image

我刚刚编写的解决方案(因此请原谅任何疏忽!)是绕过GetThumbnailAsync()获取透明PNG并生成我自己的PNG缩略图以保持透明度:

public static class ThumbnailExtensions
{
    public static async Task<IRandomAccessStream> GetTransparentThumbnailAsync(this StorageFile file, ThumbnailMode mode, uint requestedSize, ThumbnailOptions options = ThumbnailOptions.None)
    {
        if (file.FileType.ToLower() == ".png")
        {
            //try to create a scaled-down version of the PNG with transparency
            using (var fstream = await file.OpenAsync(FileAccessMode.Read))
            {
                var thumbnail = new InMemoryRandomAccessStream();
                var decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.PngDecoderId, fstream);
                var encoder = await BitmapEncoder.CreateForTranscodingAsync(thumbnail, decoder);

                encoder.BitmapTransform.ScaledHeight = requestedSize;
                encoder.BitmapTransform.ScaledWidth = requestedSize;
                encoder.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;

                await encoder.FlushAsync();
                await thumbnail.FlushAsync();
                return thumbnail;
            }
        }

        return await file.GetThumbnailAsync(mode, requestedSize, options);
    }
}

结果不是最漂亮的(甚至InterpolationMode.Fant很糟糕;但是C#的Lanczos实现在某处浮动),但它是透明的:

transparency preserved

上面的代码需要扩展,以支持保留宽高比和填充或裁剪不适合1:1的图像。