介紹
重新想象 Windows 8 Store Apps 之 圖片處理
顯示圖片
圖片的 9 切片
WriteableBitmap
獲取和修改圖片屬性
對圖片文件做“縮放/旋轉/編碼”操作,並保存 操作後的結果
示例
1、演示最基礎的圖片顯示
Image/Display.xaml
<Page x:Class="XamlDemo.Image.Display" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Image" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0" Orientation="Horizontal" VerticalAlignment="Top"> <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0"> <Image Source="/Assets/Logo.png" Stretch="Uniform" Width="200" Height="100" /> </Border> <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0"> <Image Source="ms-appx:///Assets/Logo.png" Stretch="Uniform" Width="200" Height="100" /> </Border> <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0"> <Image x:Name="img" Stretch="Uniform" Width="200" Height="100" /> </Border> <Border BorderBrush="Red" BorderThickness="1" Width="200" Height="100" Margin="20 0 0 0"> <Image x:Name="img2" Stretch="Uniform" Width="200" Height="100" /> </Border> </StackPanel> </Grid> </Page>
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; } } }
2、演示圖片的 NineGrid
Image/NineGrid.xaml
<Page x:Class="XamlDemo.Image.NineGrid" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Image" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0" Orientation="Horizontal" VerticalAlignment="Top"> <!-- Image - 圖片控件 NineGrid - 指定9網格(相當於flash中的9切片)中的4條線,Thickness 類型 Left - 左邊的線相對於圖片最左端的距離 Top - 上邊的線相對於圖片最頂端的距離 Right - 右邊的線相對於圖片最右端的距離 Bottom - 下邊的線相對於圖片最底端的距離 以下示例圖片的原始大小為 16 * 16 --> <Image Source="/Assets/NineGrid/Demo.png" Width="200" Height="200" /> <!--通過指定9切片,防止邊框被放大或縮小--> <Image Source="/Assets/NineGrid/Demo.png" Width="200" Height="200" NineGrid="1 1 1 1" Margin="20 0 0 0" /> </StackPanel> </Grid> </Page>
3、演示 WriteableBitmap 的應用
Image/WriteableBitmapDemo.xaml
<Page x:Class="XamlDemo.Image.WriteableBitmapDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Image" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <Image x:Name="img" Width="300" Height="300" HorizontalAlignment="Left" /> <Button x:Name="btnLoadImage" Content="load image" Margin="0 10 0 0" Click="btnLoadImage_Click_1" /> <Button x:Name="btnChangePixel" Content="加載一個圖片並修改其中的像素的顏色值" Margin="0 10 0 0" Click="btnChangePixel_Click_1" /> <Button x:Name="btnCreatePixel" Content="創建一個圖片,設置其每個像素的顏色值" Margin="0 10 0 0" Click="btnCreatePixel_Click_1" /> </StackPanel> </Grid> </Page>
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(); } } }
4、演示如何獲取、修改圖片屬性
Image/ImageProperty.xaml.cs
/* * 演示如何獲取、修改圖片屬性 */ 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 Task<ImageProperties> GetImageProperty(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(); } } } }
5、演示如何對圖片文件做“縮放/旋轉/編碼”操作,並保存操作後的結果
Image/ImageTransform.xaml
<Page x:Class="XamlDemo.Image.ImageTransform" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Image" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <Image x:Name="imgOriginal" Stretch="Uniform" Width="300" Height="200" HorizontalAlignment="Left" /> <Image x:Name="imgTransformed" Stretch="Uniform" Width="300" Height="200" HorizontalAlignment="Left" Margin="0 10 0 0" /> </StackPanel> </Grid> </Page>
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)); } } } } }
OK
[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar