2015-02-01 3 views
0

WPF 컨트롤에서 비트 맵을 만들고 싶습니다. 이 포럼 (일부 위의 예 : Render a "not visible" WPF controls to an bitmap image)에서 몇 가지 예를 볼 수 있지만 WPF 컨트롤이 이미 화면에 표시된 경우에만 잘 렌더링 될 수 있습니다.WPF 컨트롤에서 비트 맵 가져 오기

비트 맵 결과를 내부 비트 맵 필드에 연결하려면 모델에서 컨트롤을 만들어야합니다.

위의 스레드로 예제를 따라 갔지만 결과는 컨트롤의 내용 중 일부만 가진 비트 맵 (완전히 렌더링되지 않은 것처럼)이었습니다.

이미지를 렌더링하기 전에 전체 렌더링을 수행하는 방법은 무엇입니까?

내 소스 코드 :

if(spChart == null){ 
    String s = "<SparrowChart xmlns=\"http://sparrowtoolkit.codeplex.com/wpf\">" + 
          " <SparrowChart.XAxis>" + 
          "  <LinearXAxis/>" + 
          " </SparrowChart.XAxis>" + 
          " <SparrowChart.YAxis>" + 
          "  <LinearYAxis/>" + 
          " </SparrowChart.YAxis>" + 
          "</SparrowChart>"; 
    System.IO.StringReader stringReader = new System.IO.StringReader(s); 
    System.Xml.XmlReader xmlReader; 
       xmlReader = System.Xml.XmlReader.Create(stringReader); 
    spChart = (Sparrow.Chart.SparrowChart)System.Windows.Markup.XamlReader.Load(xmlReader); 
    spChart.XAxes[0].MinValue = 0; 
    spChart.XAxes[0].MaxValue = 10; 
    spChart.YAxes[0].MinValue = 0; 
    spChart.YAxes[0].MaxValue = 10; 
    spChart.Series.Clear(); 
} else { 
    spChart.Series.Clear(); 
} 

List<System.Drawing.PointF> points = new List<System.Drawing.PointF> {new System.Drawing.PointF(3, 7), 
                     new System.Drawing.PointF(5, 2), 
                     new System.Drawing.PointF(8, 4), 
                     new System.Drawing.PointF(4, 6)}; 
Sparrow.Chart.SeriesBase LS = new Sparrow.Chart.SplineSeries(); 
foreach(System.Drawing.PointF x in points) { 
    Sparrow.Chart.DoublePoint newPoint = new Sparrow.Chart.DoublePoint(); 
    newPoint.Data=x.X; 
    newPoint.Value=x.Y; 
} 
spChart.Series.Add(LS); 
LS = new Sparrow.Chart.ScatterSeries(); 
foreach(System.Drawing.PointF x in points) { 
    Sparrow.Chart.DoublePoint newPoint = new Sparrow.Chart.DoublePoint(); 
    newPoint.Data=x.X; 
    newPoint.Value=x.Y; 
} 
spChart.Series.Add(LS); 
spChart.Measure(new System.Windows.Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
spChart.Arrange(new System.Windows.Rect(new System.Windows.Size(1000, 1000))); 
spChart.UpdateLayout(); 

RenderTargetBitmap rtb = new RenderTargetBitmap((int)SpChart.ActualWidth, (int)SpChart.ActualHeight, 96, 96, Windows.Media.PixelFormats.Pbgra32); 
rtb.Render(spChart); 
PngBitmapEncoder png = new PngBitmapEncoder(); 
png.Frames.Add(BitmapFrame.Create(rtb)); 
MemoryStream stream = New MemoryStream(); 
png.Save(stream); 
Bitmap tmpBitmap = new Bitmap(Image.FromStream(stream)); 
bitmapToRender = MyBitmap.Clone(); 
MyBitmap.Dispose(); 

나를 위해 당신에게

루치

+0

RenderTargetBitmap 생성자의'spChart' 외에도'SpChart' 변수가 있다는 점을 제외하면 코드가 정상적으로 보입니다. 어쨌든'UpdateLayout' 다음에 (또는 대신에)'InvalidateVisual' 호출을 추가하려고 할 수 있습니다. – Clemens

+0

'SpChart'의 경우 죄송합니다. 당신이 맞습니다, 제 소스 코드는'SpChart'가 아니라'SpChart'였습니다. Sparrow 프레임 워크의 InvalidateVisual 및 UpdateLayout은 백그라운드에서 작동하며 레이아웃을 완료 할 때까지 기다려야한다고 생각합니다. RenderTerminated와 같은 이벤트를 찾지 못하면 10 밀리 초 후에 비트 맵을 저장하는 타이머를 둡니다. 이제는 내게 효과가있다. (나는 지금, orrble이다.) –

답변

1

감사,이 작품 :

Size size = new Size(432, 460); 
frameworkElement.Measure(size); 
frameworkElement.Arrange(new Rect(new Point(), size)); 
frameworkElement.UpdateLayout(); 

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap((int)frameworkElement.ActualWidth, (int)frameworkElement.ActualHeight, 96, 96, PixelFormats.Pbgra32); 
renderTargetBitmap.Render(frameworkElement); 

FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(renderTargetBitmap, PixelFormats.BlackWhite, null, 0); 

BmpBitmapEncoder bmpImage = new BmpBitmapEncoder(); 
bmpImage.Frames.Add(BitmapFrame.Create(monoBitmap)); 

byte[] bmpData; 

using (MemoryStream buffer = new MemoryStream()) 
{ 
    bmpImage.Save(buffer); 
    bmpData = buffer.ToArray(); 
} 

죄송 단색 비트 맵의 ​​결과에 대해, 그건 내가 사용한 것. 결과적으로 모든 비트 맵 유형으로 간단하게 변환 할 수 있습니다.