将FrameworkElement转换为Stream而不保存到文件

时间:2014-01-24 15:58:06

标签: c# .net windows-phone-8 nokia-imaging-sdk lumia-imaging-sdk

我想使用FrameworkElement(例如Panel)作为Image(使用Nokia Image SDK)。 我想应用效果不是在图像上而是在FrameworkElement上。

我一直在努力尝试将FrameworkElement用作writeableBitmap,然后用于我的FilterEffect的流。

这就是我所做的:

    private async void testCartoon_Tap(object sender, System.Windows.Input.GestureEventArgs e)
    {

       //the panel I want as an Image
       var rootElement = ContentPanel as FrameworkElement; 

       WriteableBitmap myWB = new WriteableBitmap(rootElement,null);

       byte[] bytes =  myWB.ToByteArray();

       MemoryStream stream = new MemoryStream();

       await stream.WriteAsync(myWB.ToByteArray(),0,bytes.Count());

       stream.Seek(0, SeekOrigin.Begin);

       var backgroundSource = new StreamImageSource(stream);

       var filterEffect = new FilterEffect(backgroundSource);

        CartoonFilter cartoonFilter = new CartoonFilter();



        filterEffect.Filters = new[] { cartoonFilter };

        var renderer = new WriteableBitmapRenderer(filterEffect, _cartoonImageBitmap);

        _cartoonImageBitmap = await renderer.RenderAsync();

        ImageCartoon.Source = _cartoonImageBitmap;
  }

CartoonFilter是NokiaImagingSDK过滤器之一。

我像这样定义了我的_cartoonImageBitmap:

  _cartoonImageBitmap = new WriteableBitmap((int)ImageCartoon.Width, (int)ImageCartoon.Height);

和xaml中的ImageCartoon:

   <Image x:Name="ImageCartoon" Width="456" Height="240" Grid.Row="1" ></Image>

我得到例外:“值不在预期范围内”行

     _cartoonImageBitmap = await renderer.RenderAsync();

你知道为什么吗?

有没有更好的方法从FrameworkElement获取流?

(我知道我可以在读取之前将writeableBitmap保存到文件存储中,但我希望避免保存图像以提高性能)。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:0)

这只是一种预感,但仍然如此。它可能值得一试。你什么时候创建_cartoonImageBitmap?看起来你是在构造函数中做的。

问题可能是你的行_cartoonImageBitmap = new WriteableBitmap((int)ImageCartoon.Width, (int)ImageCartoon.Height);在ImageCartoon初始化之前执行了它的最终大小。在构造函数中,它的大小应该仍然是(0,0)。

如果目标源的大小为(0,0),这是您从Renderer获得的错误,因此我认为值得尝试创建具有静态大小的_cartoonImageBitmap,例如(500,500)。

试试并报告!

答案 1 :(得分:0)

我找到了解决方案:问题来自WriteAsync方法。这就是我所做的:

  private async void testCartoon_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{

   //the panel I want as an Image
   var rootElement = ContentPanel as FrameworkElement; 

   WriteableBitmap myWB = new WriteableBitmap((int)rootElement.ActualWidth,    (int)rootElement.ActualHeight);
   myWB.Render(rootElement, new MatrixTransform());
   myWB.Invalidate();


    using (var stream = new MemoryStream())
    {

      myWB.SaveJpeg(stream, myWB.PixelWidth, myWB.PixelHeight, 0, 100);

      stream.Seek(0, SeekOrigin.Begin);

      var backgroundSource = new StreamImageSource(stream);

      var filterEffect = new FilterEffect(backgroundSource);

      CartoonFilter cartoonFilter = new CartoonFilter();

      filterEffect.Filters = new[] { cartoonFilter };

      var renderer = new WriteableBitmapRenderer(filterEffect, _cartoonImageBitmap);

      _cartoonImageBitmap = await renderer.RenderAsync();

      ImageCartoon.Source = _cartoonImageBitmap;
    }

}

我刚刚使用SaveJpeg进行了更改,现在可以使用了。谢谢你的帮助。