How to (correctly) copy a chart to the clip board?

5 posts, 1 answers
  1. Adam Petaccia
    Adam Petaccia avatar
    30 posts
    Member since:
    May 2010

    Posted 18 Aug 2010 Link to this post

    I would like to enable users to copy a chart to the clipboard, preserving appearance and transparency, so I've chosen to use PNG as the format.
    PngBitmapEncoder bitmapEncoder = new System.Windows.Media.Imaging.PngBitmapEncoder ();
    var chartPicture = currChart.Save (96, 96, bitmapEncoder);
    PngBitmapDecoder bitmapDecoder = new PngBitmapDecoder (chartPicture, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
     
    Clipboard.SetImage (bitmapDecoder.Frames[0]);

    However, when I paste from the clipboard, all of the transparent areas are black, which is not desirable. I don't have much experience with clip board operations, so perhaps I am doing something wrong, though other than the transparency is seem so work fine. Is there a way I can accomplish this either and either preserve the chart's transparency or at least grabbing a rendering of the chart using its current background (almost always white)?
  2. Answer
    Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 23 Aug 2010 Link to this post

    Hi Adam Petaccia,

     Clipboard supports only bitmap images. Because bitmap images don't have alpha channel, the transparency is replaced with black color. To fix this you can change the background from transparent to something else, for example - white color. Taking this into account your code can look like this:

    RadChart1.Background = Brushes.White;
    BmpBitmapEncoder bitmapEncoder = new System.Windows.Media.Imaging.BmpBitmapEncoder();
    System.IO.Stream chartPicture = RadChart1.Save(96, 96, bitmapEncoder);
    chartPicture.Seek(0, System.IO.SeekOrigin.Begin);
    BmpBitmapDecoder bitmapDecoder = new BmpBitmapDecoder(chartPicture, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    Clipboard.SetImage(bitmapDecoder.Frames[0]);


    Regards,
    Yavor Ivanov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Tony
    Tony avatar
    24 posts
    Member since:
    Sep 2014

    Posted 26 Feb 2015 in reply to Yavor Link to this post

    Hi Yavor,

    I am attempting to use the code you suggested but am running into the following error regarding the last line of code:

    ChartCtrl chartControl = (ChartCtrl)elementHost1.Child;
                chartControl.radChart.Background = System.Windows.Media.Brushes.White;
                BmpBitmapEncoder bitmapEncoder = new System.Windows.Media.Imaging.BmpBitmapEncoder();
                System.IO.Stream chartPicture = chartControl.radChart.Save(96, 96, bitmapEncoder);
                chartPicture.Seek(0, System.IO.SeekOrigin.Begin);
                BmpBitmapDecoder bitmapDecoder = new BmpBitmapDecoder(chartPicture, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    Clipboard.SetImage(bitmapDecoder.Frames[0]);

    The best overloaded method match for 'System.Windows.Forms.Clipboard.SetImage(System.Drawing.Image)' has some invalid arguments.


    I'm attempting to call it from a windows form but using an elementhost to connect to the specific radchart. I'm not sure how to resolve this.

    Thanks

    Tony

  5. Martin
    Admin
    Martin avatar
    1101 posts

    Posted 03 Mar 2015 Link to this post

    Hi Tony,

    It seems that the compile time error appears because your are using the System.Windows.Forms.Clipboard.SetImage() method, which expects an object of type System.Drawing.Image. However, the bitmapDecoder.Frames[0] element is of type System.Windows.Media.Imaging.BitmapSource and it cannot be passed to the method.

    The example given by Yavor uses the WPF's Clipboard class which is located in the System.Windows namespace.

    In order to copy the chart as an image in the clipboard you can try the following approaches:
    • Create a System.Drawing.Image object from the stream returned by the chart's Save() method and then pass it to the WinForms' Clipboard.SetImage() method.
      var img = System.Drawing.Image.FromStream(chartPicture);   
      System.Windows.Forms.Clipboard.SetImage(img);
    • Use the System.Windows.Cliboard.SetImage() method instead of the WinForms clipboard.
      System.Windows.Clipboard.SetImage(bitmapDecoder.Frames[0]);

    There is also an approach that you can use to save the image (along its transparency) as a stream. Basically you can get the stream with the image and use the System.Windows.Cliboard.SetDataObject() method. If the application that gets the stream from the clipboard implement a logic for reading images saved in this manner (as Word for example), the picture will be pasted correctly. Here is an example in code:
    using (var stream = new MemoryStream())
    {
        Telerik.Windows.Media.Imaging.ExportExtensions.ExportToImage(chartControl.radChart, stream, new PngBitmapEncoder());
        var data = new DataObject("PNG", stream);
        Clipboard.SetDataObject(data, true);
    }

    I hope this works for you.

    Regards,
    Martin
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  6. Tony
    Tony avatar
    24 posts
    Member since:
    Sep 2014

    Posted 03 Mar 2015 in reply to Martin Link to this post

    Thanks for your reply. This works.
Back to Top
UI for WPF is Visual Studio 2017 Ready