• 重新想象 Windows 8 Store Apps (29) 图片处理


    [源码下载]


    重新想象 Windows 8 Store Apps (29) - 图片处理



    作者:webabcd


    介绍
    重新想象 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 += " " + 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
    [源码下载]

  • 相关阅读:
    git的命令操作指南
    【flask】RestFul的基本鉴权
    linux断电修复
    centos7安装libreoffice
    java -jar 后台启动
    yum安装nginx
    rpm安装mysql
    yum安装redis
    Centos 修改yum源
    centos8安装node.js v12.18.3
  • 原文地址:https://www.cnblogs.com/webabcd/p/3101069.html
Copyright © 2020-2023  润新知