我现在正在学习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);
}
}
}
感谢您的帮助!
答案 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();
}
}