重新想象 Windows 8 Store Apps (29) - 图片处理
作者:介绍重新想象 Windows 8 Store Apps 之 图片处理 - 显示图片
- 图片的 9 切片
- WriteableBitmap
- 获取和修改图片属性
- 对图片文件做“缩放/旋转/编码”操作,并保存操作后的结果
Image/Display.xaml.cs
/* * 演示最基础的图片显示 * * 注: * 1、引用 package 中的图片用:ms-appx:/// * 2、引用 ApplicationData 中的图片: * a) LocalFolder 对应 ms-appdata:///local/ * b) RoamingFolder 对应 ms-appdata:///roaming/ * c) TemporaryFolder 对应 ms-appdata:///temp/ */using System;using Windows.Storage.Streams;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Media.Imaging;using Windows.UI.Xaml.Navigation;namespace XamlDemo.Image{ public sealed partial class Display : Page { public Display() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { // code-behind 指定图片源 img.Source = new BitmapImage(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute)); // code-behind 指定图片源 RandomAccessStreamReference imageStreamRef = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute)); IRandomAccessStream imageStream = await imageStreamRef.OpenReadAsync(); BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(imageStream); img2.Source = bitmapImage; } }}
Image/WriteableBitmapDemo.xaml.cs
/* * 演示 WriteableBitmap 的应用 * * 注:WriteableBitmap 使用的是 BGRA 格式 */using Windows.UI.Xaml;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Media.Imaging;using System;using System.IO;using System.Runtime.InteropServices.WindowsRuntime;using Windows.Graphics.Imaging;using Windows.Storage;using Windows.Storage.Streams;namespace XamlDemo.Image{ public sealed partial class WriteableBitmapDemo : Page { public WriteableBitmapDemo() { this.InitializeComponent(); } // 加载一个图片 private async void btnLoadImage_Click_1(object sender, RoutedEventArgs e) { // 实例化一个 300*300 的 WriteableBitmap,并将其作为 Image 控件的图片源 WriteableBitmap writeableBitmap = new WriteableBitmap(300, 300); img.Source = writeableBitmap; StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png")); using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read)) { // 设置 WriteableBitmap 对象的图片流 await writeableBitmap.SetSourceAsync(fileStream); } } // 加载一个图片并修改其中的像素的颜色值 private async void btnChangePixel_Click_1(object sender, RoutedEventArgs e) { // 实例化一个 300*300 的 WriteableBitmap,并将其作为 Image 控件的图片源 WriteableBitmap writeableBitmap = new WriteableBitmap(300, 300); img.Source = writeableBitmap; StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png")); using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read)) { // 将指定的图片转换成 BitmapDecoder 对象 BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream); // 通过 BitmapTransform 缩放图片的尺寸 BitmapTransform transform = new BitmapTransform() { ScaledWidth = Convert.ToUInt32(writeableBitmap.PixelWidth), ScaledHeight = Convert.ToUInt32(writeableBitmap.PixelHeight) }; // 获取图片的 PixelDataProvider 对象 PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, transform, ExifOrientationMode.IgnoreExifOrientation, ColorManagementMode.DoNotColorManage); // 获取图片的像素数据,由于之前指定的格式是 BitmapPixelFormat.Bgra8,所以每一个像素由 4 个字节组成,分别是 bgra byte[] sourcePixels = pixelData.DetachPixelData(); for (int i = 0; i < sourcePixels.Length; i++) { sourcePixels[i] -= 10; } // 将修改后的像素数据写入 WriteableBitmap 对象的像素缓冲区(WriteableBitmap 使用的是 BGRA 格式) using (Stream stream = writeableBitmap.PixelBuffer.AsStream()) // IBuffer.AsStream() 为来自 System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions 中的扩展方法 { await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length); } } // 用像素缓冲区的数据绘制图片 writeableBitmap.Invalidate(); } // 创建一个图片,设置其每个像素的颜色值 private async void btnCreatePixel_Click_1(object sender, RoutedEventArgs e) { // 实例化一个 300*300 的 WriteableBitmap,并将其作为 Image 控件的图片源 WriteableBitmap writeableBitmap = new WriteableBitmap(300, 300); img.Source = writeableBitmap; Random random = new Random(); // 设置需要绘制的图片的像素数据(每一个像素由 4 个字节组成,分别是 bgra) byte[] result = new byte[300 * 300 * 4]; for (int i = 0; i < result.Length; ) { result[i++] = (byte)random.Next(0, 256); // Green result[i++] = (byte)random.Next(0, 256); // Blue result[i++] = (byte)random.Next(0, 256); // Red result[i++] = 255; // Alpha } // 将像素数据写入 WriteableBitmap 对象的像素缓冲区 using (Stream stream = writeableBitmap.PixelBuffer.AsStream()) { await stream.WriteAsync(result, 0, result.Length); } // 用像素缓冲区的数据绘制图片 writeableBitmap.Invalidate(); } }}
/* * 演示如何获取、修改图片属性 */using System;using System.Threading.Tasks;using Windows.Storage;using Windows.Storage.FileProperties;using Windows.Storage.Pickers;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation;using XamlDemo.Common;namespace XamlDemo.Image{ public sealed partial class ImageProperty : Page { public ImageProperty() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { if (Helper.EnsureUnsnapped()) { // 选择一个图片文件 FileOpenPicker picker = new FileOpenPicker(); picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; picker.FileTypeFilter.Add(".jpg"); picker.FileTypeFilter.Add(".png"); StorageFile file = await picker.PickSingleFileAsync(); if (file != null) { ImageProperties imageProperties = await GetImageProperty(file); UpdateImageProperty(imageProperties); } } } // 获取图片属性 private async TaskGetImageProperty(StorageFile file) { // 获取图片文件的图片属性信息 ImageProperties imageProperties = await file.Properties.GetImagePropertiesAsync(); // 显示图片文件的图片属性(以下试举几例,不全) lblMsg.Text = "title: " + imageProperties.Title; lblMsg.Text += Environment.NewLine; lblMsg.Text += "keywords: " + string.Join(",", imageProperties.Keywords); lblMsg.Text += Environment.NewLine; lblMsg.Text += "width: " + imageProperties.Width; lblMsg.Text += Environment.NewLine; lblMsg.Text += "height: " + imageProperties.Height; lblMsg.Text += Environment.NewLine; return imageProperties; } // 更新图片属性 private async void UpdateImageProperty(ImageProperties imageProperties) { Random random = new Random(); // 设置图片文件的图片属性(以下试举几例,不全) imageProperties.Title = random.Next(0, 1000).ToString(); imageProperties.Keywords.Clear(); imageProperties.Keywords.Add(random.Next(0, 1000).ToString()); imageProperties.Keywords.Add(random.Next(0, 1000).ToString()); try { // 保存图片文件的图片属性信息 await imageProperties.SavePropertiesAsync(); lblMsg.Text += "title 和 keywords 已被修改,重新进来可看效果"; } catch (Exception ex) { lblMsg.Text = ex.ToString(); } } }}
Image/ImageTransform.xaml.cs
/* * 演示如何对图片文件做“缩放/旋转/编码”操作,并保存操作后的结果 */using System;using Windows.Graphics.Imaging;using Windows.Storage;using Windows.Storage.Pickers;using Windows.Storage.Streams;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Media.Imaging;using Windows.UI.Xaml.Navigation;using XamlDemo.Common;namespace XamlDemo.Image{ public sealed partial class ImageTransform : Page { public ImageTransform() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { if (Helper.EnsureUnsnapped()) { // 选择一个 .jpg 图片文件 FileOpenPicker picker = new FileOpenPicker(); picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary; picker.FileTypeFilter.Add(".jpg"); StorageFile fileRead = await picker.PickSingleFileAsync(); if (fileRead != null) { // 显示用户选中的图片文件 BitmapImage src = new BitmapImage(); src.SetSource(await fileRead.OpenAsync(FileAccessMode.Read)); imgOriginal.Source = src; // 定义一个转换后的图片文件 StorageFile fileWrite = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(@"webabcdTest\imageTransformDemo.png", CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream inputStream = await fileRead.OpenAsync(FileAccessMode.Read), outputStream = await fileWrite.OpenAsync(FileAccessMode.ReadWrite)) { // 将用户选择的图片文件转换为一个 BitmapDecoder 对象 BitmapDecoder decoder = await BitmapDecoder.CreateAsync(inputStream); // 通过 BitmapTransform 来配置图片的宽度、高度和顺时针旋转角度 BitmapTransform transform = new BitmapTransform(); transform.ScaledWidth = 100; transform.ScaledHeight = 100; transform.Rotation = BitmapRotation.Clockwise180Degrees; // 获取图片的 PixelDataProvider 对象 PixelDataProvider pixelProvider = await decoder.GetPixelDataAsync( decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb ); // 获取经过了 BitmapTransform 转换后的图片的像素数据 byte[] pixels = pixelProvider.DetachPixelData(); // 创建一个 BitmapEncoder 对象,可以指定图片的编码格式(PngEncoderId, JpegEncoderId, JpegXREncoderId, GifEncoderId, TiffEncoderId) BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, outputStream); // 转码像素数据到指定的图片编码格式(本例会转吗为 png 格式),并将转码后的数据写入 stream 缓冲区 encoder.SetPixelData( decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, 100, 100, decoder.DpiX, decoder.DpiY, pixels ); // 提交 stream 缓冲区中的所有内容 await encoder.FlushAsync(); } // 显示经过“缩放/旋转/编码”操作后的图片文件 imgTransformed.Source = new BitmapImage(new Uri("ms-appdata:///temp/webabcdTest/imageTransformDemo.png", UriKind.Absolute)); } } } }}