正在将WPF InkCanvas保存到JPG-图像被裁剪

正在将WPF InkCanvas保存到JPG-图像被裁剪,wpf,image,inkcanvas,Wpf,Image,Inkcanvas,我有一个WPF InkCanvas控件,用于在应用程序中捕获签名。控件看起来像这样-它是700x300 但是,当我将其保存为JPG时,生成的图像看起来是这样的,也是700x300 我用来保存的代码 sigPath = System.IO.Path.GetTempFileName(); MemoryStream ms = new MemoryStream(); FileStream fs = new FileStre

我有一个WPF InkCanvas控件,用于在应用程序中捕获签名。控件看起来像这样-它是700x300

但是,当我将其保存为JPG时,生成的图像看起来是这样的,也是700x300

我用来保存的代码

            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>

标签
拯救
取消
清楚的


在过去,这种方法非常有效。我不知道是什么改变导致图像在保存时发生移动。

啊哈!问题在于InkCanvas正上方的TextBlock txtLabel。当您删除该选项时,黑线将消失


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

杰森,我解决了这个问题。 对不起,我的英语不好。我是俄罗斯人。 您需要在
0,0,0,0
与:

保存后,在您的位置设置边距

例如: 和 表面。边缘=新厚度(55,40,96,5);

我的班级保存图像

     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);
    }

我也有同样的问题。。它在这里起作用了

    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;
    } 
private void按钮\u单击(对象发送者,路由目标)
{           
双倍宽度=inkSig.ActualWidth;
双倍高度=inkSig.实际高度;
RenderTargetBitmap bmpCopied=新的RenderTargetBitmap((int)Math.Round(width),(int)Math.Round(height),96,96,PixelFormats.Default);
DrawingVisual dv=新DrawingVisual();
使用(DrawingContext dc=dv.RenderOpen())
{
VisualBrush vb=新的VisualBrush(inkSig);
DrawRectangle(vb,null,new Rect(new System.Windows.Point(),new System.Windows.Size(width,height));
}
bmpCopied.Render(dv);
System.Drawing.Bitmap位图;
使用(MemoryStream outStream=新MemoryStream())
{
//从System.Media.BitmapImage到System.Drawing.Bitmap
BitMapEnc=新的BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bmpCopied));
加密保存(扩展);
位图=新系统.绘图.位图(扩展);
}
编码器参数质量参数=
新编码器参数(System.Drawing.Imaging.Encoder.Quality,85L);
//Jpeg图像编解码器
ImageCodecInfo jpegCodec=getEncoderInfo(“图像/jpeg”);
如果(JPEG编解码器==null)
返回;
EncoderParameters encoderParams=新的EncoderParameters(1);
encoderParams.Param[0]=qualityParam;
位图btm=新位图(位图);
Dispose();
保存(“C:\\Users\\Pd\\Desktop\\dfe12.jpg”、JPEG编解码器、编码器参数);
btm.Dispose();
}
私有ImageCodeInfo getEncoderInfo(字符串mimeType)
{
//获取所有图像格式的图像编解码器
ImageCodecInfo[]codecs=ImageCodecInfo.GetImageEncoders();
//找到正确的图像编解码器
对于(int i=0;i
我一直在网上寻找这个问题的答案,并尝试了大多数意见,但毫无乐趣。然后我尝试了这个,它成功了

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

        </InkCanvas>
</Canvas>


我为此制作了一个小样本,并使用您的精确代码保存了一个.jpg。我做了各种各样的图片,我一次也不能重现这个问题!它一定在其他地方-你能发布你的XAML和其他相关的东西吗?谢谢这似乎奏效了。但愿我也明白为什么。我想我现在会删除文本块,等我有更多时间来研究它时再尝试。它这样做是因为你使用的是StackPanel。不同的布局面板对你的控件做了一些鬼鬼祟祟的事情。。。在您的例子中,您很可能会看到一个偏移变换应用于InkCanvas。我想你可以把你的墨水画布放在一个边框里来绕过它。有关更多信息,请参阅此链接:在InkCanvas周围添加边框确实有帮助。只需确保边框和画布的尺寸相等。从上面的代码中,inkCanvas边框问题可能会被删除。试试这个。
  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); 
<Canvas x:Name="editCanvas" Background="Transparent" ClipToBounds="True">
        <InkCanvas EditingMode="Select" x:Name="inkCanvas"  Background="Transparent" Height="562" Width="866">

        </InkCanvas>
</Canvas>