代码之家  ›  专栏  ›  技术社区  ›  Jason

将WPF InkCanvas保存到JPG-图像将被剪切

  •  4
  • Jason  · 技术社区  · 15 年前

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

    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>
    

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

    7 回复  |  直到 9 年前
        1
  •  2
  •   Charlie    15 年前

    啊哈!问题是文本块 TXTLAMP 就在画布的正上方。当你移除黑线时,黑线就消失了。

    至于为什么会这样,我还不完全确定。

        2
  •  5
  •   Arthur    13 年前

    我也有同样的问题,我是这样做的……它在这里起作用。

        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;
        } 
    
        3
  •  3
  •   user241423    15 年前

    我的班级保存图像

         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);
        }
    
        4
  •  1
  •   user241423    15 年前

    杰森我解决了这个问题。 对不起,我的英语。我是俄国人。 需要设置InkCanvas属性。边距为0,0,0,0 那个 表面.边缘=新厚度(0,0,0,0); 在你的位置保存了设定的利润之后

    Expple: 我纳威

    表面.边缘=新厚度(0,0,0,0); http://img189.imageshack.us/img189/7499/mynewimage.png

        5
  •  1
  •   user241423    15 年前

    和 表面.边缘=新厚度(55,40,96,5); http://img519.imageshack.us/img519/7499/mynewimage.png

        6
  •  0
  •   Thirumalai murugan JJacquelin    10 年前
      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); 
    
        7
  •  0
  •   user4964503    9 年前

    我一直在网上寻找这个问题的答案,并毫无喜悦地尝试了大多数意见。然后我试了一下,结果成功了!

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