2009-08-05 4 views
4

У меня есть элемент управления InkCanvas WPF, который я использую для захвата подписи в моем приложении. Управления выглядит следующим образом - это 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

ответ

2

Aha! Проблема заключается в TextBlock txtLabel, который находится непосредственно над InkCanvas. Когда вы удаляете, черная линия исчезает.

Что касается того, почему это происходит, я еще не совсем уверен.

+0

спасибо! - похоже, это трюк. Хотел бы я понять, почему тоже. Наверное, сейчас я удалю TextBlock и повторю попытку позже, когда у меня будет больше времени, чтобы углубиться в это. – Jason

+2

Это делается потому, что вы используете StackPanel. Различные панели макетов делают некоторые подлые вещи для ваших элементов управления ...в вашем случае вы, скорее всего, видите преобразование смещения, применяемое к вашему InkCanvas. Я думаю, вы можете обойти это, поместив свой InkCanvas в пограничный. См. Эту ссылку для получения дополнительной информации: http://blogs.msdn.com/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx –

+0

Добавление границы вокруг InkCanvas действительно помогает. Просто убедитесь, что ваша граница и холст имеют одинаковые размеры. –

1

Jason i solvo эта проблема. Извините, мой английский. Я русский. Вам необходимо установить свойство inkCanvas.Margin - 0,0,0,0 , что surface.Margin = new Толщина (0, 0, 0, 0); после сохранения заданного запаса в вас posicion

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

Из вышеприведенного кода проблема с краской canvas может быть удалена. Попробуй это. – 2014-10-14 06:18:12

0

Я искал во всем net для ответа на эту проблему и без всякой радости пробовал большинство мнений. Тогда я попробовал это, и это сработало!

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

     </InkCanvas> 
</Canvas>