2009-08-05 40 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>