2011-09-27 9 views
6

私はユーザーに表示しているチャートを持っています。チャートをディスクにイメージとしてエクスポートして、アプリケーション(プレゼンテーションなど)。UIElementのイメージを画面に表示されたものよりも大きくレンダリングしました

私はPngBitmapEncoderとRenderTargetBitmapを使って基本的な考え方を手に入れましたが、私がそこから抜け出すイメージは、実際に使用するには小さかったので、はるかに大きなイメージを得たいと思います。

レンダリングしたいコントロールの高さと幅を単純に大きくしようとしましたが、親がレンダーサイズを直接制御しているようです。これから、UIElementをメモリに複製しようとしましたが、レンダリングサイズは(0,0)でした.Array()やUpdateLayout()など、レンダリングするためにメソッドを使用しようとすると、親を分離する必要がありますが、それは記憶にあり、レンダリングされていないので、親ではないはずです。それが動作しない以外

これは、すべてのVisibloxがここAPI

をグラフ化して行われているが、私は現在持っているものである:(

var width = 1600; 
var height = 1200; 

var newChart = new Chart { Width = width, Height = height, Title = chart.Title, XAxis = chart.XAxis, YAxis = chart.YAxis, Series = chart.Series}; 
Debug.WriteLine(newChart.RenderSize); 
var size = new Size(width, height); 
newChart.Measure(size); 
newChart.Arrange(new Rect(size)); 
newChart.UpdateLayout(); 
Debug.WriteLine(newChart.RenderSize); 

var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); 
      rtb.Render(newChart); 

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

using (var stream = fileDialog.OpenFile()) 
    encoder.Save(stream); 

私はそれが今、少し近い得ていますグラフの背景軸などが、ただではないグラフ化されている実際の行をレンダリング以下

public static void RenderChartToImage(Chart elementToRender, string filename) 
{ 
    if (elementToRender == null) 
     return; 
    Debug.Write(elementToRender.RenderSize); 
    var clone = new Chart(); 

    clone.Width = clone.Height = double.NaN; 
    clone.HorizontalAlignment = HorizontalAlignment.Stretch; 
    clone.VerticalAlignment = VerticalAlignment.Stretch; 
    clone.Margin = new Thickness(); 

    clone.Title = elementToRender.Title; 
    clone.XAxis = new DateTimeAxis(); 
    clone.YAxis = new LinearAxis() { Range = Range<double>)elementToRender.YAxis.Range}; 

    foreach (var series in elementToRender.Series) 
    { 
     var lineSeries = new LineSeries 
          { 
           LineStroke = (series as LineSeries).LineStroke, 
           DataSeries = series.DataSeries 
          }; 
     clone.Series.Add(lineSeries); 
    } 


    var size = new Size(1600, 1200); 

    clone.Measure(size); 
    clone.Arrange(new Rect(size)); 
    clone.UpdateLayout(); 

    Debug.Write(clone.RenderSize); 

    var height = (int)clone.ActualHeight; 
    var width = (int)clone.ActualWidth; 

    var renderer = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Pbgra32); 

    renderer.Render(clone); 

    var pngEncoder = new PngBitmapEncoder(); 
    pngEncoder.Frames.Add(BitmapFrame.Create(renderer)); 

    using (var file = File.Create(filename)) 
    { 
     pngEncoder.Save(file); 
    } 
} 

は、だから私はこのような何かを出す更新されたソースです。 をchart

大きくはあるものの、グラフ化されていないので便利ではありません。

+0

進捗状況 – Technicolour

答えて

3

http://www.visiblox.com/blog/2011/05/printing-visiblox-charts

私が行方不明になった主なポイントは

InvalidationHandler.ForceImmediateInvalidate = true; 

私はメモリ内にグラフを描画する前にこれを設定してから、私は終わっていた後、それを元に戻すでした。そこから滑らかな航海でした:D

1

私は、これらが役立つかもしれないと思う:ダウンロードsilverlight solution

Exporting Visifire Silverlight Chart as Imageを。

Exporting Chart as Image in WPF

+0

ありがとう、残念ながら、私は他の場所でも読んだことがありますが、それは現在レンダリングされているサイズサイズを指定して、そのコントロールをユーザーに与えることができるようにしたい(つまり、プレゼンテーションのために大きなグラフをエクスポートする) – Technicolour

2
RenderTargetBitmap DrawToImage<T>(T source, double scale) where T:FrameworkElement 
{ 
    var clone = Clone(source); 
    clone.Width = clone.Height = Double.NaN; 
    clone.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; 
    clone.VerticalAlignment = System.Windows.VerticalAlignment.Stretch; 
    clone.Margin = new Thickness(); 
    var size = new Size(source.ActualWidth * scale, source.ActualHeight * scale); 
    clone.Measure(size); 
    clone.Arrange(new Rect(size)); 

    var renderBitmap = new RenderTargetBitmap((int)clone.ActualWidth, (int)clone.ActualHeight, 96, 96, PixelFormats.Pbgra32); 
    renderBitmap.Render(clone); 
    return renderBitmap; 
} 

static T Clone<T>(T source) where T:UIElement 
{ 
    if (source == null) 
     return null; 
    string xaml = XamlWriter.Save(source); 
    var reader = new StringReader(xaml); 
    var xmlReader = XmlTextReader.Create(reader, new XmlReaderSettings()); 
    return (T)XamlReader.Load(xmlReader); 
} 
+0

残念ながら、ストリングへのシリアル化とクローンメソッド内でのバックアウトのどちらも、それは単に非常に長い時間を取っているだけです(私は〜50k +ポイントを扱っています) – Technicolour