提出问题提出问题
 

已答复Save DrawingGroup to jpg file

  • 2008年6月2日 15:01Wuzza 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     包含代码
    Hi All,

    I'm a struggling WPF newbie in need of guidance.

    I have a DrawingGroup containing two Drawing objects, one is a product image, the other a watermark with low opacity.  All I want to do is save this DrawingGroup as a jpg image.

    The JpegBitmapEncoder requies a BitmapFrame which in turn requires a BitmapSource.  But, I can't figure out how to efficiently create a BitmapSource based upon my DrawingGroup.  Surely I am missing something very simple?

    I do have a working solution (shown below) but it seems overly convoluted and performs very slowly.
    //1. Create a DrawingImage based on the DrawingGroup
    DrawingImage myDrawingImg = new DrawingImage(myDrawingGroup);

    //2. Create an Image control which will accept the DrawingImage as its Source
    System.Windows.Controls.Image myImage = new Image();
    myImage.Source = myDrawingImg;
    myImage.Arrange(new Rect(0,0, 500, 500));  //Required

    //3. Render the Image control's content to a RenderTargetBitmap
    RenderTargetBitmap rtb = new RenderTargetBitmap(500, 500, 96, 96, System.Windows.Media.PixelFormats.Default);
    rtb.Render(myImage);

    //4. Now the RenderTargetBitmap can be used with the JpegBitmapEncoder
    myEncoder.Frames.Add(BitmapFrame.Create(rtb));

    I'd really appreciate any tips on how to improve the performance of the above code.
    -Warwick

答案

  • 2008年6月2日 23:16Mike Cook - MSFT 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    Hi Warwick,

    This looks to be the shortest path from DrawingGroup to a jpeg file, you don't appear to be doing anything obviously terrible here.  I'd like to get a little more information about your problem.  Can you tell me a more about how this code is performing and how far short of your expectation this is?

    RenderTargetBitmap forces a render in software likely introducing a performance hit if your DrawingGroup is overly complex.  I wouldn't expect anything too extreme though, and this appears to be unavoidable anyway.

    I'd also be happy to profile your code and provide some feedback if you have a simple repro.

    -Mike
    Mike Cook - Microsoft Developer
    • 已标记为答案Wuzza 2008年6月3日 8:55
    •  

全部回复

  • 2008年6月2日 23:16Mike Cook - MSFT 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     已答复
    Hi Warwick,

    This looks to be the shortest path from DrawingGroup to a jpeg file, you don't appear to be doing anything obviously terrible here.  I'd like to get a little more information about your problem.  Can you tell me a more about how this code is performing and how far short of your expectation this is?

    RenderTargetBitmap forces a render in software likely introducing a performance hit if your DrawingGroup is overly complex.  I wouldn't expect anything too extreme though, and this appears to be unavoidable anyway.

    I'd also be happy to profile your code and provide some feedback if you have a simple repro.

    -Mike
    Mike Cook - Microsoft Developer
    • 已标记为答案Wuzza 2008年6月3日 8:55
    •  
  • 2008年6月3日 8:55Wuzza 用户奖牌用户奖牌用户奖牌用户奖牌用户奖牌
     

    Hi Mike,

    Thanks for your message and for verifying that my solution is OK. 
     
    My app will be used to watermark images for use on our website, they are 600 pixels square.  I have a slider control which is used to adjust the opacity of the watermark Drawing and another to adjust the jpg compression level.  On each adjustment I write the watermarked image to a stream (so that I can show the file size)  and then display the jpg on screen.
     
    I’ve run Perforator on my app, it appears that the software rendering causes a slow down by an order of magnitude.  When adjusting the opacity slider I see roughly 2 updates per second.   For comparison, when I remove the code shown in my original post, the updates jump to 23 per second.  In this test I can’t write the watermarked image to a stream, instead I write and display just the watermark layer.

    I appreciate your offer to profile my code, but I do not think that it would be time well spent, my app is for internal use only and its performance isn’t critical.   I am happy to know that I should stop looking for a faster solution and will live with it as is.

    Many Thanks,

    - Warwick