程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows 8 Store Apps學習(29) 圖片處理

Windows 8 Store Apps學習(29) 圖片處理

編輯:關於.NET

介紹

重新想象 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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved