0

I am writing an app in C#4.0/WPF that displays a piece of machinery in an image control within a canvas. 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. 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! 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. Hope some one can help! Many Thanks, Jeff and apologies for the long posting!

Test App 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#

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]

Main app 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#

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]

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;

}
}
4

2 回答 2

0

您如何将其添加到您的画布并摆脱背景?:

画布名称="canvBlade1Image" 边距="33,23,719,6">

...画布上的其他东西
Image Source="C:\Users\jeff\documents\blankblade.png"/>

/帆布>

于 2013-01-24T17:42:38.513 回答
0

经过很多挫折,我现在已经能够解决这个问题。我无法找出为什么我的 prod 应用程序中没有使用与我成功的测试应用程序完全相同的代码来呈现背景。因此,我尝试了一种显式渲染背景的新方法。这有效,代码如下:

       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);
              }
          }
于 2013-01-30T12:23:04.720 回答