2009-08-05 39 views
4

我有一个WPF InkCanvas控件,用于在我的应用程序中捕获签名。控制是这样的 - 这是700x300将WPF InkCanvas保存为JPG - 图像被裁剪

alt text http://img156.imageshack.us/img156/7885/inkcanvas.jpg

然而,当我把它保存为JPG,生成的图像看起来是这样,也700x300

alt text http://img210.imageshack.us/img210/5668/saved.jpg

我的代码使用保存

  sigPath = System.IO.Path.GetTempFileName(); 

      MemoryStream ms = new MemoryStream(); 
      FileStream fs = new FileStream(sigPath, FileMode.Create); 

      RenderTargetBitmap rtb = new RenderTargetBitmap((int)inkSig.Width, (int)inkSig.Height, 96d, 96d, PixelFormats.Default); 
      rtb.Render(inkSig); 
      JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
      encoder.Frames.Add(BitmapFrame.Create(rtb)); 

      encoder.Save(fs); 
      fs.Close(); 

这是我使用的XAML:

<Window x:Class="Consent.Client.SigPanel" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Background="Transparent" Topmost="True" AllowsTransparency="True" 
Title="SigPanel" Left="0" Top="0" Height="1024" Width="768" WindowStyle ="None" ShowInTaskbar="False" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" > 

<Border BorderThickness="1" BorderBrush="Black" Background='#FFFFFFFF' x:Name='DocumentRoot' Width='750' Height='400' CornerRadius='10'> 
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <TextBlock Name="txtLabel" FontSize="24" HorizontalAlignment="Center" >Label</TextBlock> 
     <InkCanvas Opacity="1" Background="Beige" Name="inkSig" Width="700" Height="300" /> 

     <StackPanel HorizontalAlignment="Center" Orientation="Horizontal"> 
      <Button FontSize="24" Margin="10" Width="150" Name="btnSave" Click="btnSave_Click">Save</Button> 
      <Button FontSize="24" Margin="10" Width="150" Name="btnCancel" Click="btnCancel_Click">Cancel</Button> 
      <Button FontSize="24" Margin="10" Width="150" Name="btnClear" Click="btnClear_Click">Clear</Button> 
     </StackPanel> 
    </StackPanel> 
</Border> 

在过去,这完美地工作。我无法弄清楚在保存时导致图像移动的变化。

+0

我为此做了一个小样本,并使用您的确切代码来保存.jpg。我做了各种各样的图像,而且我一次都不能重现这个问题! 它必须在别的地方 - 你可以发布你的XAML和其他可能相关的东西吗? – Charlie 2009-08-05 17:31:36

回答

2

啊哈!问题是直接位于InkCanvas上方的TextBlock txtLabel。当你删除黑线消失。

至于为什么发生这种情况,我还不完全确定。

+0

谢谢! - 这似乎是诀窍。希望我也明白为什么。我想我现在将删除TextBlock,稍后再试一次,当我有更多时间来深入研究。 – Jason 2009-08-05 20:28:50

+2

这是因为你正在使用StackPanel。各种布局面板为你的控件做了一些鬼鬼祟祟的东西......在你的情况下,你最有可能看到一个偏移转换被应用到你的InkCanvas。我认为你可以通过将InkCanvas放入边框来避开它。有关详细信息,请参阅此链接:http://blogs.msdn.com/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx – 2009-10-09 19:28:50

+0

在InkCanvas周围添加边框确实有帮助。只要确保你的边框和画布有相同的尺寸。 – 2014-03-04 08:44:47

1

杰森我解决了这个问题。 对不起我的英文。我是俄国人。 您需要设置属性inkCanvas.Margin是0,0,0,0 即 surface.Margin = new Thickness(0,0,0,0); 节省集余量在你职位后

的exaple: 我中堂

surface.Margin =新厚度(0,0,0,0); http://img189.imageshack.us/img189/7499/mynewimage.png

2

我班保存图像

 using System; 
    using System.IO; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Media; 
    using System.Windows.Media.Imaging; 

    public void ExportToJpeg(String path, InkCanvas surface) 
    { 
     double 
       x1 = surface.Margin.Left, 
       x2 = surface.Margin.Top, 
       x3 = surface.Margin.Right, 
       x4 = surface.Margin.Bottom; 

     if (path == null) return; 

     surface.Margin = new Thickness(0, 0, 0, 0); 

     Size size = new Size(surface.Width, surface.Height); 
    surface.Measure(size); 
    surface.Arrange(new Rect(size)); 

     RenderTargetBitmap renderBitmap = 
      new RenderTargetBitmap(
      (int)size.Width, 
      (int)size.Height, 
      96, 
      96, 
      PixelFormats.Default); 
     renderBitmap.Render(surface); 
     using (FileStream fs = File.Open(path, FileMode.Create)) 
     { 
     JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
      encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); 
      encoder.Save(fs); 
     } 
     surface.Margin = new Thickness(x1, x2, x3, x4); 
    } 
5

我有同样的问题,我这样做的方式。它在这里工作了..

private void Button_Click(object sender, RoutedEventArgs e) 
    {   
     double width = inkSig.ActualWidth; 
     double height = inkSig.ActualHeight; 
     RenderTargetBitmap bmpCopied = new RenderTargetBitmap((int)Math.Round(width), (int)Math.Round(height), 96, 96, PixelFormats.Default); 
     DrawingVisual dv = new DrawingVisual(); 
     using (DrawingContext dc = dv.RenderOpen()) 
     { 
      VisualBrush vb = new VisualBrush(inkSig); 
      dc.DrawRectangle(vb, null, new Rect(new System.Windows.Point(), new System.Windows.Size(width, height))); 
     } 
     bmpCopied.Render(dv); 
     System.Drawing.Bitmap bitmap; 
     using (MemoryStream outStream = new MemoryStream()) 
     { 
      // from System.Media.BitmapImage to System.Drawing.Bitmap 
      BitmapEncoder enc = new BmpBitmapEncoder(); 
      enc.Frames.Add(BitmapFrame.Create(bmpCopied)); 
      enc.Save(outStream); 
      bitmap = new System.Drawing.Bitmap(outStream); 
     } 

     EncoderParameter qualityParam = 
    new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 85L); 

     // Jpeg image codec 
     ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg"); 

     if (jpegCodec == null) 
      return; 

     EncoderParameters encoderParams = new EncoderParameters(1); 
     encoderParams.Param[0] = qualityParam; 
     Bitmap btm = new Bitmap(bitmap); 
     bitmap.Dispose(); 
     btm.Save("C:\\Users\\Pd\\Desktop\\dfe12.jpg", jpegCodec, encoderParams); 
     btm.Dispose(); 
    } 

    private ImageCodecInfo getEncoderInfo(string mimeType) 
    { 
     // Get image codecs for all image formats 
     ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 

     // Find the correct image codec 
     for (int i = 0; i < codecs.Length; i++) 
      if (codecs[i].MimeType == mimeType) 
       return codecs[i]; 
     return null; 
    } 
0
var size = new Size(inkCanvas.ActualWidth, inkCanvas.ActualHeight); 
    inkCanvas.Margin = new Thickness(0, 0, 0, 0); 

    inkCanvas.Measure(size); 
    inkCanvas.Arrange(new Rect(size)); 
    var encoder = new PngBitmapEncoder(); 
    var bitmapTarget = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Default); 
    bitmapTarget.Render(inkCanvas); 
    encoder.Frames.Add(BitmapFrame.Create(bitmapTarget)); 
    encoder.Save(ms); 
+0

从上面的代码可能会删除inkCanvas边框问题。尝试这个。 – 2014-10-14 06:18:12

0

我一直在寻找所有的网络为这个问题的答案,并尝试大多数意见没有任何喜悦。然后我尝试了这个,它工作!

<Canvas x:Name="editCanvas" Background="Transparent" ClipToBounds="True"> 
     <InkCanvas EditingMode="Select" x:Name="inkCanvas" Background="Transparent" Height="562" Width="866"> 

     </InkCanvas> 
</Canvas>