WPF InkCanvas - 保存的图像为黑色

时间:2017-05-12 14:25:33

标签: c# wpf bitmap savefiledialog inkcanvas

我现在正在学习WPF和C#,为此我试图实现一个小的绘图应用程序。 为此,我使用InkCanvas,我想将其保存为.jpg ord .png图像。

我从这里获得了保存InkCanvas的代码:Convert WPF InkCanvas to Bitmap 但是我没有将其转换为字节数组,而是试图使用SaveFileDialog直接保存它。

保存画布后的结果:尺寸没问题,就像Canvas的尺寸一样。但是保存.jpg是完全黑色的,我不知道为什么。

我搜索了这个问题并偶然发现了这个问题:Stackoverflow - InkCanvas to BitMap 所以我尝试将我的InkCanvas放入几个容器中,没有任何其他内容,但没有任何变化,保存的图像仍然是黑色的。 我发现的第二个链接就是这个:Stackoverflow - saving WPF InkCanvas to a JPG - image is getting cropped 我的项目中没有TextBox,因此我尝试删除其他Control元素,但结果相同。保存的图像仍然是黑色。

我甚至尝试使用不同的PixelFormats,保存它没有边距等等。我有什么遗漏吗?

XAML的代码:

   <Grid>
    <DockPanel>
        <Menu DockPanel.Dock="Top" Height="30" Background="#252629" FontSize="18" Foreground="#dddddd" Panel.ZIndex="999">
            <MenuItem Header="_File">
                <MenuItem x:Name="mnuItmNew" Header="_New Image" Background="#252629" Click="mnuNewImage_Click"/>
                <MenuItem x:Name="mnuItmOpen" Header="_Open Image" Background="#252629"/>
                <MenuItem x:Name="mnuItmSave" Header="_Save" Background="#252629" IsEnabled="False"/>
                <MenuItem x:Name="mnuItmSaveAs" Header="_Save as" Background="#252629" IsEnabled="False"/>
                <MenuItem x:Name="mnuItmExport" Header="_Export" Background="#252629" IsEnabled="False" Click="mnuExport_Click"/>
                <MenuItem x:Name="mnuItmExit" Header="_Exit" Background="#252629" Click="mnuExit_Click"/>
            </MenuItem>
            <MenuItem Header="_Edit">
                <MenuItem Header="_Resize Canvas" Background="#252629"/>
                <MenuItem Header="_Settings" Background="#252629"/>
            </MenuItem>
            <MenuItem Header="_?">
                <MenuItem Header="_Help" Background="#252629"/>
                <MenuItem Header="_About" Click="mnuAbout_Click" Background="#252629"/>
            </MenuItem>
        </Menu>
        <StackPanel DockPanel.Dock="Top" Height="30" Orientation="Horizontal" Background="#252629" Panel.ZIndex="999">

        </StackPanel>
        <StackPanel DockPanel.Dock="Bottom" Height="20" Orientation="Horizontal" Background="#353639" Panel.ZIndex="999">

        </StackPanel>
        <StackPanel DockPanel.Dock="Right" Width="300" Orientation="Vertical" Margin="0,1,0,1" Background="#252629" Panel.ZIndex="999">

        </StackPanel>
        <StackPanel DockPanel.Dock="Right" Width="50" Orientation="Vertical" Margin="0,1,1,1" Background="#252629" Panel.ZIndex="999">
            <Button x:Name="btnHand" Width="50" Height="50" Background="#252629" BorderThickness="0" Content="Hand" Click="btnHand_Click"/>
            <Button x:Name="btnPen" Width="50" Height="50" Background="#252629" BorderThickness="0" Content="Pen" Click="btnPen_Click"/>
            <Button x:Name="btnErase" Width="50" Height="50" Background="#252629" BorderThickness="0" Content="Erase" Click="btnErase_Click"/>
            <Button x:Name="btnFill" Width="50" Height="50" Background="#252629" BorderThickness="0" Content="Fill" Click="btnFill_Click"/>
            <Button x:Name="btnColPick" Width="50" Height="50" Background="#252629" BorderThickness="0" Content="Pick" Click="btnColPick_Click"/>
        </StackPanel>
        <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
            <Grid>
                <Grid x:Name="drawPanel">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="50"/>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="50"/>
                        <RowDefinition Height="1*"/>
                        <RowDefinition Height="50"/>
                    </Grid.RowDefinitions>
                    <Canvas DockPanel.Dock="Top" Background="#151619" Height="50" Grid.ColumnSpan="3"/>
                    <Canvas DockPanel.Dock="Bottom" Background="#151619" Height="50" Grid.ColumnSpan="3"/>
                    <Canvas DockPanel.Dock="Left" Background="#151619" Width="50" Grid.RowSpan="3"/>
                    <Canvas DockPanel.Dock="Right" Background="#151619" Width="50" Grid.RowSpan="3"/>
                    <Canvas x:Name="canvasDrawBackground" Grid.Column="1" Grid.Row="1" Height="0" Width="0" IsEnabled="False">
                        <Canvas.Background>
                            <VisualBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="0,0,20,20">
                                <VisualBrush.Visual>
                                    <Image Source="images/drawBoardTile.png"></Image>
                                </VisualBrush.Visual>
                            </VisualBrush>
                        </Canvas.Background>
                    </Canvas>
                    <InkCanvas x:Name="canvasDraw" Background="Transparent" Height="0" Width="0" Grid.Row="1" Grid.Column="1" IsEnabled="False" EditingModeInverted="EraseByPoint"/>
                </Grid>
            </Grid>
        </ScrollViewer>
    </DockPanel>
</Grid>

C#代码保存

        private void mnuExport_Click(object sender, RoutedEventArgs e)
    {
        Microsoft.Win32.SaveFileDialog dlgSave = new Microsoft.Win32.SaveFileDialog();
        dlgSave.FileName = "unnamed"; // Default file name
        dlgSave.DefaultExt = ".jpg"; // Default file extension
        dlgSave.Filter = "Image (.jpg)|*.jpg"; // Filter files by extension

        // Show save file dialog box
        Nullable<bool> result = dlgSave.ShowDialog();

        // Process save file dialog box results
        if (result == true)
        {
            // Save document
            string filename = dlgSave.FileName;
            //get the dimensions of the ink control
            int margin = (int)this.canvasDraw.Margin.Left;
            int width = (int)this.canvasDraw.ActualWidth - margin;
            int height = (int)this.canvasDraw.ActualHeight - margin;
            //render ink to bitmap
            RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Default);
            rtb.Render(canvasDraw);

            //saving bitmap
            using (FileStream savestream = new FileStream(filename, FileMode.Create))
            {
                BmpBitmapEncoder encoder = new BmpBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(rtb));
                encoder.Save(savestream);
            }
        }
    }

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

    public void saveCanvas()
    {
        string subpath = Directory.GetCurrentDirectory();
        SaveFileDialog saveFileDialog12 = new SaveFileDialog();
        saveFileDialog12.Filter = "JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|Png File|*.png";
        saveFileDialog12.Title = "Save an Image File";
        saveFileDialog12.InitialDirectory = subpath;
        saveFileDialog12.ShowDialog();

        if (saveFileDialog12.FileName == "") return;
        subpath = saveFileDialog12.FileName.Substring(0, saveFileDialog12.FileName.Length - saveFileDialog12.SafeFileName.Length);

        string extension = saveFileDialog12.FileName.Remove(subpath.IndexOf(subpath), subpath.Length);
        string[] allStr = extension.Split('.');

        string fileName = allStr[0];
        string folderName = fileName + "_" + allStr[1];
        folderName = subpath + folderName;

        Directory.CreateDirectory(folderName);
        DirectoryInfo dInfo = new DirectoryInfo(folderName);
        DirectorySecurity dSecurity = dInfo.GetAccessControl();
        dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
        dInfo.SetAccessControl(dSecurity);

        string saveFile = folderName + "\\" + fileName + "_";
        for (int i = 0; i < listCanvas.Count; i++)
        {
            RenderTargetBitmap rtb = new RenderTargetBitmap((int)listCanvas[i].Width, (int)listCanvas[i].Height, 96d, 96d, PixelFormats.Default);
            rtb.Render(listCanvas[i]);
            DrawingVisual dvInk = new DrawingVisual();
            DrawingContext dcInk = dvInk.RenderOpen();
            dcInk.DrawRectangle(listCanvas[i].Background, null, new Rect(0d, 0d, listCanvas[i].Width, listCanvas[i].Height));
            foreach (System.Windows.Ink.Stroke stroke in listCanvas[i].Strokes)
            {
                stroke.Draw(dcInk);
            }
            dcInk.Close();

            FileStream fs = File.Open(saveFile + (i + 1).ToString() + "." + allStr[1], FileMode.OpenOrCreate);//save bitmap to file
            System.Windows.Media.Imaging.JpegBitmapEncoder encoder1 = new JpegBitmapEncoder();
            encoder1.Frames.Add(BitmapFrame.Create(rtb));
            encoder1.Save(fs);
            fs.Close();
        }
    }