从非Freezable图像创建Freezable图像

时间:2017-01-14 02:49:01

标签: wpf

我有一个DrawingImage,它使用DynamicResources作为颜色。我想在动画中使用该图像,但是你不能在动画中使用动态资源的对象,因为它们不是Freezable。我知道在动画中我的颜色不能动态变化,我不在乎。我只是想创建一个我可以在动画中使用的图像版本。因此,基本上让图像评估其所有资源,然后吐出一个我可以称之为Freeze的版本,以便在动画中使用。当然这一定是可能的吗?例如,我必须能够将此图像写入磁盘吗?那必须创建一个Freezable版本,不是吗?我已经用Google搜索并搜索了StackOverflow,但却找不到任何有用的信息......非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

这很难找到解决方案,但我似乎找到了一个。我做了这个方便的扩展,它将接受我的DrawingImage并通过PngBitmapEncoder将其编码为PNG,然后将其写入内存流,然后将其加载到BitmapImage中,该BitmapImage是Freezable并且可以在我的动画中使用。整个lotta的工作非常简单!

public static class DrawingExtensions
{
    public static BitmapImage GetAsFreezableBitmapImage(this DrawingImage drawingImage)
    {
        return drawingImage?.Drawing?.GetAsFreezableBitmapImage();
    }

    public static BitmapImage GetAsFreezableBitmapImage(this Drawing drawing)
    {
        if (drawing == null)
            return null;

        var drawingVisual = new DrawingVisual();

        using (var drawingContext = drawingVisual.RenderOpen())
        {
            drawingContext.PushTransform(new TranslateTransform(-drawing.Bounds.X, -drawing.Bounds.Y));
            drawingContext.DrawDrawing(drawing);
        }

        var bitmap = new RenderTargetBitmap((int)drawing.Bounds.Width, (int)drawing.Bounds.Height, 96, 96, PixelFormats.Pbgra32);
        bitmap.Render(drawingVisual);

        var encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmap));

        var bitmapImage = new BitmapImage();
        using (var stream = new MemoryStream())
        {
            encoder.Save(stream);
            bitmapImage.BeginInit();
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.StreamSource = stream;
            bitmapImage.DecodePixelHeight = bitmap.PixelHeight;
            bitmapImage.DecodePixelWidth = bitmap.PixelWidth;
            bitmapImage.EndInit();
        }

        return bitmapImage;
    }
}