如何在 WPF C# 中覆盖(使用)BitmapFrame.Thumbnail 属性?

Posted

技术标签:

【中文标题】如何在 WPF C# 中覆盖(使用)BitmapFrame.Thumbnail 属性?【英文标题】:How to override(use) BitmapFrame.Thumbnail property in WPF C#? 【发布时间】:2020-01-01 12:31:38 【问题描述】:

你好!问题是?我有一个多页 Tiff 文件要显示,我使用 BitmapFrame.Thumbnail 属性显示我的多页 Tiff 文件的每一帧(页面)的小尺寸缩略图。但是

我已经尝试使用这种方法创建自己的 BitmapSource 缩略图:

public static BitmapImage GetThumbnail(BitmapFrame bitmapFrame)
        
            try
            
                JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                MemoryStream memorystream = new MemoryStream();
                BitmapImage tmpImage = new BitmapImage();
                encoder.Frames.Add(bitmapFrame);
                encoder.Save(memorystream);
                tmpImage.BeginInit();
                tmpImage.CacheOption = BitmapCacheOption.OnLoad;
                tmpImage.StreamSource = new MemoryStream(memorystream.ToArray());
                File.WriteAllBytes( $"Path.GetTempFileName().jpg", memorystream.ToArray());
                tmpImage.UriSource = new Uri($"Path.GetTempFileName().jpg");
                tmpImage.DecodePixelWidth = 80;
                tmpImage.DecodePixelHeight = 120;
                tmpImage.EndInit();
                memorystream.Close();
                return tmpImage;
            
            catch (Exception ex)
            
                return null;
                throw ex;
            
         

然后我将结果转换为 BitmapSource 并使用以下命令创建 BitmapFrames 列表:

List<BitmapFrame> tiffImageList = new List<BitmapFrame>();
tiffImageList.Add(new TiffImage()  index = imageIndex, image = BitmapFrame.Create(frame, (BitmapSource)GetThumbnail(frame)));

最后我尝试获取属性,但它返回 null:

foreach (var tiffImage in tiffImageList)

   Image image = new Image();
   image.Source = tiffImage.image.Thumbnail;

【问题讨论】:

请注意,如果您已经将位图帧编码到 MemoryStream 中,则根本不需要将其写入文件并从该文件中解码另一个图像。只需通过设置新的 BitmapImage 的 StreamSource 属性(如tmpImage.StreamSource = memoryStream;)直接从 MemoryStream 解码。不要忘记预先倒带流,例如通过将其位置设置为零。 我也怀疑创建这些缩略图是否有用。由于您已经解码了全尺寸帧,您可以简单地显示一个带有 ScaleTransform 的 TransformedBitmap。 谢谢你的评论,我会尝试改变方法,使用TransformedBitmap等 【参考方案1】:

我遇到了类似的问题,使用 SDK PhotoViewerDemo 示例进行修改。一些有效的 jpg 显示为白色方形缩略图。

我想我找到了问题代码不起作用的原因。 Ivan 的问题提供了正确的 BitmapFrame 构造函数,但函数必须创建 BitmapSource,而不是 BitmapImage。

C# BitmapFrame.Thumbnail property is null for some images

我使用该主题中提供的函数,使用 Ivan 对构造函数的调用,使用 两个 位图源参数。

我现在使用的 SDK 示例中的代码是..

    private BitmapSource CreateBitmapSource(Uri path)
    
        BitmapImage bmpImage = new BitmapImage();
        bmpImage.BeginInit();
        bmpImage.UriSource = path;
        bmpImage.EndInit();
        return bmpImage;
    

    private BitmapSource CreateThumbnail(Uri path)
    
        BitmapImage bmpImage = new BitmapImage();
        bmpImage.BeginInit();
        bmpImage.UriSource = path;
        bmpImage.DecodePixelWidth = 120;
        bmpImage.EndInit();
        return bmpImage;
    

    // it has to be plugged in here,
    public Photo(string path)
    
        Source = path;
        _source = new Uri(path);
        // replaced.. Image = BitmapFrame.Create(_source);
        // with this:
        Image = BitmapFrame.Create(CreateBitmapSource(_source),CreateThumbnail(_source));
        Metadata = new ExifMetadata(_source);
    

【讨论】:

以上是关于如何在 WPF C# 中覆盖(使用)BitmapFrame.Thumbnail 属性?的主要内容,如果未能解决你的问题,请参考以下文章

C# WPF 多个window 相互覆盖的次序控制 不用topmost

C# WPF MVVM开发框架Caliburn.Micro 名称Transformer⑩①

如何使用一种方法在网格 C# WPF 中添加行 [重复]

WPF C# 实现鼠标穿透窗体

如何扩展而不是覆盖 WPF 样式

如何在 c# wpf 中使用本地数据库 .sdf?