问题:需要将缩放和其它处理后的图片保存成图片,采用一般的将控件保存成图片的方法,发现导出的图片内容为空或者显示不完整。
<Window x:Class="Image_Zoom_Save.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Image_Zoom_Save"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Image Name="imgProcess" Stretch="Uniform" RenderOptions.BitmapScalingMode="HighQuality"/>
</ScrollViewer>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="Load" Margin="5" Click="Load_Click"/>
<Button Content="Save" Margin="5" Click="Save_Click"/>
<Slider Name="sliderZoom" Minimum="0.2" Maximum="5" Value="1" VerticalAlignment="Center" Width="200"
ValueChanged="SliderZoom_ValueChanged"/>
<Label Name="lblInfo"/>
<Button Content="Change Position" Margin="5" Click="Position_Click"/>
</StackPanel>
</Grid>
</Window>
using System;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace Image_Zoom_Save
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private BitmapImage bitmapImage;
public MainWindow()
{
InitializeComponent();
}
private void SliderZoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (bitmapImage == null)
{
return;
}
imgProcess.Width = sliderZoom.Value * bitmapImage.Width;
imgProcess.Height = sliderZoom.Value * bitmapImage.Height;
lblInfo.Content = "width = " + ((int)imgProcess.Width).ToString() + "; height = " + ((int)imgProcess.Height).ToString();
}
private void Load_Click(object sender, RoutedEventArgs e)
{
bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.UriSource = new Uri("D:/MyPrograms/图标/qq.png", UriKind.RelativeOrAbsolute);
bitmapImage.EndInit();
imgProcess.Source = bitmapImage;
imgProcess.Width = bitmapImage.Width;
imgProcess.Height = bitmapImage.Height;
imgProcess.VerticalAlignment = VerticalAlignment.Center;
imgProcess.HorizontalAlignment = HorizontalAlignment.Center;
lblInfo.Content = "width = " + ((int)imgProcess.Width).ToString() + "; height = " + ((int)imgProcess.Height).ToString();
}
private void UISaveToImage(FrameworkElement ui, string fileName, int width, int height)
{
RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96d, 96d, PixelFormats.Pbgra32);
bmp.Render(ui);
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
FileStream fs = new FileStream(fileName, FileMode.Create);
encoder.Save(fs);
fs.Close();
}
private void Save_Click(object sender, RoutedEventArgs e)
{
UISaveToImage(imgProcess, "test.png", (int)imgProcess.Width, (int)imgProcess.Height);
}
private void Position_Click(object sender, RoutedEventArgs e)
{
imgProcess.VerticalAlignment = VerticalAlignment.Top;
imgProcess.HorizontalAlignment = HorizontalAlignment.Left;
}
}
}
补充说明:放大功能没有利用RenderTransform属性,而是仅仅改变imgProcess的宽度和高度;这种保存控件为图片的方式似乎要求对象位置为父对象的左上角,不过这样显示的效果不尽人意,有什么好的方法吗?发现用Canvas.GetTop(imgProcess)得到的结果是NaN,so weird。