2009-08-05 2 views
4

내 응용 프로그램에서 서명을 캡처하는 데 사용하는 WPF InkCanvas 컨트롤이 있습니다. 컨트롤은 다음과 같습니다 - 나는 JPG로 저장할 때, 그러나 alt text http://img156.imageshack.us/img156/7885/inkcanvas.jpgWPF InkCanvas를 JPG에 저장 - 이미지가 잘 리면서 나타납니다.

700x300

있어, 결과 이미지는, 다음과 같이 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

아하! 문제는 InkCanvas 바로 위에있는 TextBlock txtLabel입니다. 제거하면 검은 선이 사라집니다.

왜 그런 일이 벌어지고 있는지에 대해서는 아직 확실하지 않습니다.

+0

! 그 트릭을하는 것처럼 보였습니다. 내가 왜 그렇게 이해했으면 좋겠어. 이제 TextBlock을 제거하고 나중에이 문제를 탐구 할 시간이있을 때 다시 시도해 보겠습니다. – Jason

+2

StackPanel을 사용하기 때문에 이렇게하는 것입니다. 다양한 레이아웃 패널은 여러분의 컨트롤에 어떤 비열한 것들을합니다 ...귀하의 경우 InkCanvas에 적용되는 오프셋 변환이 가장 잘 보입니다. InkCanvas를 테두리에 넣으면 주위를 둘러 볼 수 있다고 생각합니다. 자세한 내용은이 링크를 참조하십시오. http://blogs.msdn.com/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx –

+0

InkCanvas 주위에 테두리를 추가하면 도움이됩니다. 테두리와 캔버스의 치수가 동일해야합니다. –

1

제이슨 솔 바로이 문제. 죄송합니다 내 영어. 저는 러시아인입니다. 설정 속성이 필요합니다. inkCanvas.Margin은 0,0,0,0 입니다. 표면입니다. 마진 = 새 두께 (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

위 코드에서 inkCanvas 경계 문제가 제거 될 수 있습니다. 이 시도. –

0

했다 이 문제에 대한 답변을 얻으 려하고 기쁨없이 대부분의 의견을 시도했습니다. 그런 다음 나는 이것을 시도하고 그것은 효과가있다!

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

     </InkCanvas> 
</Canvas> 
관련 문제