[英]Render Canvas with Background to Bitmap fails to display background C#/WPF
I am writing an app in C#4.0/WPF that displays a piece of machinery in an image control within a canvas. 我正在用C#4.0 / WPF编写一个应用程序,该应用程序在画布中的图像控件中显示一块机器。 The user drags coloured text blocks on to the image to indicate an area of wear or damage (I have written code that creates and moves a new text block as a user drags it).
用户将彩色文本块拖到图像上以指示磨损或损坏的区域(我编写了在用户拖动时创建并移动新文本块的代码)。 Once the user has completed dragging the text blocks on the canvas my aim is to capture background and text blocks in a bitmap to be sent to a report.
用户完成在画布上拖动文本框后,我的目标是捕获位图中的背景和文本框,以将其发送到报告。 The trouble is that when I try and do this the image that is captured shows only the text blocks that have been dragged and not the background.
麻烦在于,当我尝试执行此操作时,捕获的图像仅显示已拖动的文本块,而不显示背景。 I have created a test project with what looks like exactly the same code to me and it captures the canvas with all contents perfectly.
我创建了一个测试项目,其代码对我来说似乎完全相同,并且可以完美捕获所有内容的画布。 I have not included the code that performs the text block dragging in the test project as I dont think it is relevant, however I have included it here for clarity.
我认为在测试项目中没有包含执行文本块拖动的代码,因为我认为这并不重要,但是为了清楚起见,在此处将其包括在内。 I have included the relevant code from both the main and test app.
我已经包含了来自主应用程序和测试应用程序的相关代码。 I have also included images produced in both the main and test apps.
我还包括了在主应用程序和测试应用程序中生成的图像。 I am not too hot on XAML so I suspect this is where the fault lies.
我对XAML不太热衷,所以我怀疑这是问题所在。 I have tried to post images from both test and main apps but the site will not allow as I have less than 10 rep points!
我尝试过发布来自测试应用程序和主要应用程序的图像,但是该网站不允许,因为我的代表积分少于10分! I can of course do this once I have the points.I have not included all XAML for the form as it is a big form and there is a lot of code - I can do this if required though.I have researched high and low and have posted this on other forums with no luck.
一旦掌握了要点,我当然可以执行此操作。我没有将所有XAML都包含在该表单中,因为它是一个很大的表单,并且有很多代码-但是我可以根据需要执行此操作。在其他论坛上都没有运气。 Hope some one can help!
希望有人能帮忙! Many Thanks, Jeff and apologies for the long posting!
非常感谢,杰夫(Jeff)和冗长的歉意!
Test App XAML: 测试应用XAML:
<Canvas Name="canvBlade1Image" Margin="33,23,719,6">
<TextBlock Height="15" Name="tblkRed" Width="18" FontSize="11" Background="Red" Canvas.Left="200" Canvas.Top="444" HorizontalAlignment="Center" TextAlignment="Center" />
<TextBlock Background="Orange" FontSize="11" Height="15" Name="tblkOrange" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="465" />
<TextBlock Background="Yellow" FontSize="11" Height="15" Name="tblkYellow" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="486" />
<TextBlock Background="Lime" FontSize="11" Height="15" Name="tblkGreen" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="508" />
<TextBlock Background="DodgerBlue" FontSize="11" Height="15" Name="tblkGre" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="528" />
<Canvas.Background>
<ImageBrush ImageSource="C:\Users\jeff\documents\blankblade.png" Stretch="Fill"></ImageBrush>
</Canvas.Background>
test app C# 测试应用C#
private void btnRendertoBitmap_Click(object sender, RoutedEventArgs e)
{
Transform transform = canvBlade1Image.LayoutTransform;
canvBlade1Image.LayoutTransform = null;
Size size = new Size(canvBlade1Image.ActualWidth, canvBlade1Image.ActualHeight);
canvBlade1Image.Measure(size);
canvBlade1Image.Arrange(new Rect(size));
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(canvBlade1Image);
using (FileStream outStream = new FileStream(@"C:\Users\jeff\documents\blade.png.", FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
} }
![test app output][1] ![测试应用程序输出] [1]
Main app XAML 主应用程序XAML
<Canvas Name="canvBlade1Image" Margin="33,23,719,6">
<TextBlock Height="15" Name="tblkRed" Width="18" FontSize="11" Background="Red" Canvas.Left="200" Canvas.Top="444" HorizontalAlignment="Center" TextAlignment="Center" />
<TextBlock Background="Orange" FontSize="11" Height="15" Name="tblkOrange" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="465" />
<TextBlock Background="Yellow" FontSize="11" Height="15" Name="tblkYellow" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="486" />
<TextBlock Background="Lime" FontSize="11" Height="15" Name="tblkGreen" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="508" />
<TextBlock Background="DodgerBlue" FontSize="11" Height="15" Name="tblkGre" TextAlignment="Center" Width="18" Canvas.Left="200" Canvas.Top="528" />
<Canvas.Background>
<ImageBrush ImageSource="C:\Users\jeff\documents\blankblade.png" Stretch="Fill"></ImageBrush>
</Canvas.Background>
Main App C# 主应用C#
public bool ExportToPNG()
{
try
{
Transform transform = canvBlade1Image.LayoutTransform;
canvBlade1Image.LayoutTransform = null;
Size size = new Size(canvBlade1Image.ActualWidth, canvBlade1Image.ActualHeight);
canvBlade1Image.Measure(size);
canvBlade1Image.Arrange(new Rect(size));
RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(canvBlade1Image);
using (FileStream outStream = new FileStream(@"C:\Users\jeff\documents\blade.png.", FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
return true;
}
catch (Exception E)
{
MessageBox.Show("Error converting blade image" + E);
return false;
}
}
![Main app output][2] ![主要应用输出] [2]
Code to drag textblocks 拖动文本块的代码
private void canvBlade1Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if(doNotAllowNewFault == true && (((System.Windows.Controls.TextBlock)(e.Source)).Text == ""))
{
return;
}
if (e.Source != canvBlade1Image && e.Source.GetType() == typeof(System.Windows.Controls.TextBlock))
{
overlayTextBlockBackgroundBrush = ((System.Windows.Controls.TextBlock)(e.Source)).Background;
overlayTextBlockTextAlignment = TextAlignment.Center;
overlayTextBlockFontSize = ((System.Windows.Controls.TextBlock)(e.Source)).FontSize;
overlayTextBlockText = ((System.Windows.Controls.TextBlock)(e.Source)).Text;
canvBlade1Image.Children.Remove(sourceTextBlock);
if(((System.Windows.Controls.TextBlock)(e.Source)).Text !="")
{
moveFault = true;
}
sourceElementLeft = Canvas.GetLeft((TextBlock)e.Source);
sourceElementTop = Canvas.GetLeft((TextBlock)e.Source);
canvBlade1Image.Children.Remove(sourceTextBlock);
sourceTextBlock = (TextBlock)e.Source;
mIsDown = true;
mStartPoint = e.GetPosition(canvBlade1Image);
e.Handled = true;
}
}
private void canvBlade1Image_MouseMove(object sender, MouseEventArgs e)
{
Double actualX = Math.Abs(e.GetPosition(canvBlade1Image).X);
Double startX = mStartPoint.X;
Double actualY = Math.Abs(e.GetPosition(canvBlade1Image).Y);
Double startY = mStartPoint.Y;
if (mIsDown)
{
if (!mIsDragging)
{
DragStarted();
}
}
if (mIsDragging)
{
DragMoved();
}
e.Handled = true;
}
private void DragStarted()
{
mIsDragging = true;
sourceElementLeft = Canvas.GetLeft(sourceTextBlock);
sourceElementTop = Canvas.GetTop(sourceTextBlock);
overlayTextBlock = new TextBlock();
overlayTextBlock.Background = sourceTextBlock.Background;
overlayTextBlock.Width = sourceTextBlock.RenderSize.Width;
overlayTextBlock.Height = sourceTextBlock.RenderSize.Height;
if (moveFault == false)
{
overlayTextBlock.Text = blade1FaultNumber.ToString();
}
else
{
overlayTextBlock.Text =overlayTextBlockText;
}
overlayTextBlock.FontSize = overlayTextBlockFontSize;
overlayTextBlock.TextAlignment = overlayTextBlockTextAlignment;
canvBlade1Image.Children.Add(overlayTextBlock);
overlayTextBlock.Opacity = 1;
}
private void DragMoved()
{
Point currentPosition = Mouse.GetPosition(canvBlade1Image);
double elementLeft = (currentPosition.X - mStartPoint.X) + sourceElementLeft;
double elementTop = (currentPosition.Y - mStartPoint.Y) + sourceElementTop;
Canvas.SetLeft(overlayTextBlock, elementLeft);
Canvas.SetTop(overlayTextBlock, elementTop);
}
private void canvBlade1Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (mIsDown)
{
DragFinished(false);
e.Handled = true;
}
}
private void DragFinished(Boolean cancelled)
{
if (mIsDragging)
{
if( moveFault)
{
canvBlade1Image.Children.Remove(sourceTextBlock);
}
else
{
Canvas.SetLeft(sourceTextBlock, Canvas.GetLeft(overlayTextBlock));
Canvas.SetTop(sourceTextBlock, Canvas.GetTop(overlayTextBlock));
TextBlock replacementTextBlock = new TextBlock();
Canvas.SetLeft(replacementTextBlock, sourceElementLeft);
Canvas.SetTop(replacementTextBlock, sourceElementTop);
replacementTextBlock.Height = overlayTextBlock.Height;
replacementTextBlock.Width = overlayTextBlock.Width;
replacementTextBlock.Opacity = 1;
replacementTextBlock.FontSize = 11;
replacementTextBlock.Background = overlayTextBlock.Background;
blade1FaultNumber++;
canvBlade1Image.Children.Add(replacementTextBlock);
}
moveFault = false;
overlayTextBlock = null;
mIsDragging = false;
mIsDown = false;
txtFaultBriefDesciption1.IsEnabled = true;
txtFaultdetails1.IsEnabled = true;
cboMeters1.IsEnabled = true;
}
}
How about you add this to your canvas and get rid of the background?: 您如何将其添加到画布并摆脱背景呢?:
Canvas Name="canvBlade1Image" Margin="33,23,719,6">
画布名称=“ canvBlade1Image” Margin =“ 33,23,719,6”>
...other stuff on canvas
...画布上的其他东西
Image Source="C:\\Users\\jeff\\documents\\blankblade.png"/>图片来源=“ C:\\ Users \\ jeff \\ documents \\ blankblade.png” />
/Canvas>
/画布>
After much frustration I have now been able to resolve this issue. 经过许多挫折后,我现在已经能够解决此问题。 I was unable to find out why the background was not rendering in my prod app with exactly the same code as my successful test app.
我无法找出为什么背景与我成功的测试应用程序完全相同的代码无法在我的产品应用程序中呈现。 I therefore tried a new route of explicitly rendering the background.
因此,我尝试了一条显式渲染背景的新路线。 This worked, code below:
这行得通,代码如下:
try
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
(int)canvBlade1Image.ActualWidth,(int)canvBlade1Image.ActualHeight,96d,
96d, PixelFormats.Pbgra32);
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
drawingContext.DrawRectangle(canvBlade1Image.Background, null, new Rect(0, 0, canvBlade1Image.ActualWidth, canvBlade1Image.ActualHeight));
renderBitmap.Render(drawingVisual);
renderBitmap.Render(canvBlade1Image);
using (FileStream outStream = new FileStream(@"C:\Images\Keep\img1.png.", FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
encoder.Save(outStream);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.