zoukankan      html  css  js  c++  java
  • 42、XAML Images

    1、Displaying images :

        在 xaml 中引用程序包中的图片的方法 :

     <Image Source="Assets/image1.jpg" Height="200" />

    2、Images from  a  file stream:

          本实例演示用户通过 File Picker 选择图片,并且进行编码解析。

    操作截图:

    原始图片:

    经过解析:

    页面的 XAML :

    <!--高度-->
     <TextBox x:Name="Scenario2DecodePixelHeight"  Width="100" Text="100" HorizontalAlignment="Left" />
    
     <!--宽度-->
     <TextBox x:Name="Scenario2DecodePixelWidth"  Width="100" Text="100" HorizontalAlignment="Left" />
    
     <!-- 点击打开 FileOpenPicker. -->
     <Button x:Name="Scenario2Button1" Content="Select image..."  Click = “Scenario2Button1_Click”/>
     
    <!--显示结果-->
    <Image x:Name="Scenario2Image" Stretch="None" />


    相应的 C# :

    按钮的单击事件:

    async void Scenario2Button1_Click(object sender, RoutedEventArgs e)
    {
        int decodePixelHeight;
        int decodePixelWidth;
    
          if (!int.TryParse(Scenario2DecodePixelHeight.Text, out decodePixelHeight))
        {
            Scenario2DecodePixelHeight.Text = "100";
            decodePixelHeight = 100;
        }
    
        if (!int.TryParse(Scenario2DecodePixelWidth.Text, out decodePixelWidth))
        {
            Scenario2DecodePixelWidth.Text = "100";
            decodePixelWidth = 100;
        }
    
        FileOpenPicker open = new FileOpenPicker();
        open.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        open.ViewMode = PickerViewMode.Thumbnail;
    
        // Filter to include a sample subset of file types
        open.FileTypeFilter.Clear();
        open.FileTypeFilter.Add(".bmp");
        open.FileTypeFilter.Add(".png");
        open.FileTypeFilter.Add(".jpeg");
        open.FileTypeFilter.Add(".jpg");
    
    
        StorageFile file = await open.PickSingleFileAsync();
    
        if (file != null)
        {
            using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
    
                BitmapImage bitmapImage = new BitmapImage();
    
                 //获取或设置要用于图像编码操作的高度。
                bitmapImage.DecodePixelHeight = decodePixelHeight;
                bitmapImage.DecodePixelWidth = decodePixelWidth;
    
                await bitmapImage.SetSourceAsync(fileStream);
                Scenario2Image.Source = bitmapImage;
            }
        }
    }

    3、Displaying a NineGrid image :

          下面的实例展示了怎样使用 NineGrid margins 显示一个图片。

          第一张图片是原始图片(8x7 像素)。第二张是把原图片放大到 100x200 的图片。第三张图片是放大到 100x200 并且指定

     了 3 像素的 NineGrid margins 。这些控件使用拉伸边缘和边角的行为。

       NineGrid  属性: 获取或设置控制图像大小调整方式的九格形式的值。

    显示截图 :

    相应的 xaml :

     <Image Source="Assets/NineGridSource.png"  Stretch="None" />
    
     <Image Source="Assets/NineGridSource.png"/>
    
    <!--NineGrid :  获取或设置控制图像大小调整方式的九格形式的值。-->
    <Image Source="Assets/NineGridSource.png" NineGrid="3,3,3,3"/>


    4、Using a WriteableBitmap :

         下面的演示展示了如何直接操作  WriteableBitmap  对象的像素点。

          首先在 XAML 页面中,放置三个按钮 和 一个显示图片操作结果的容器 :

    <!--异步绘制曼德尔勃特集合,并且将结果显示在下面的  WriteableBitmap 中。-->
    <Button   Content="Draw Mandelbrot set" Click="DrawMandelbrotSet_Click" />
    
    
    <!--加载一个选取的图片,并使用  SetSource  方法将其显示在 WriteableBitmap 中-->
     <Button x:Name="Scenario4SetSourceButton"              Content="Load image using SetSource" Click="LoadImageUsingSetSource_Click" />
    
    
    <!--加载一个选择的图片,并使用  BitmapDecoder 解码像素并复制到  WriteableBitmap 中。-->
    <Button x:Name="Scenario4LoadImageButton"       Content="Load image using PixelBuffer" Click="LoadImageUsingPixelBuffer_Click" />


    显示结果的容器:

    <Viewbox Width="400" Height="300" x:Name="Scenario4ImageContainer">
        <Image x:Name="Scenario4Image" />
    </Viewbox>            


    在相应的  C# 中,定义一个全局的  WriteableBitmap:

     
    //下面的操作都是用这个对象
    private WriteableBitmap Scenario4WriteableBitmap;

    在页面的构造函数中,使用 Image 控件的容器 Scenario4ImageContainer 控件的尺寸初始化这个对象:

     Scenario4WriteableBitmap = new WriteableBitmap((int)Scenario4ImageContainer.Width, (int)Scenario4ImageContainer.Height);
     Scenario4Image.Source = Scenario4WriteableBitmap;


    第一个按钮的单击事件:

    private async void DrawMandelbrotSet_Click(object sender, RoutedEventArgs e)
            {
                  int pixelWidth = Scenario4WriteableBitmap.PixelWidth;
                int pixelHeight = Scenario4WriteableBitmap.PixelHeight;
    
                // 在一个后台线程中异步绘制 曼德尔勃特集
                byte[] result = null;
                await ThreadPool.RunAsync(new WorkItemHandler(
                    (IAsyncAction action) =>
                    {
                        result = DrawMandelbrotGraph(pixelWidth, pixelHeight);
                    }
                    ));
    
                // 打开一个流,用来复制图片到  WriteableBitmap的 像素缓冲区
                using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream())
                {
                    await stream.WriteAsync(result, 0, result.Length);
                }
    
                // 绘制  WriteableBitmap
                Scenario4WriteableBitmap.Invalidate(); //请求绘制或重绘整个位图。
            }
    
            private byte[] DrawMandelbrotGraph(int width, int height)
            {
                //每个像素需要 4 字节
                byte[] result = new byte[width * height * 4];
                int resultIndex = 0;
    
                // 当测试时,最大次数的迭代,来判断一个点是否在这个集中
                int maxIterationCount = 50;
    
                // 选择间隔
                //Complex : 表示一个复数。
                Complex minimum = new Complex(-2.5, -1.0);
                Complex maximum = new Complex(1.0, 1);
    
                // Normalize x and y values based on chosen interval and size of WriteableBitmap
                double xScaleFactor = (maximum.Real - minimum.Real) / width;
                double yScaleFactor = (maximum.Imaginary - minimum.Imaginary) / height;
    
                //在 xy 平面绘制 曼德尔勃特集
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        Complex c = new Complex(minimum.Real + x * xScaleFactor, maximum.Imaginary - y * yScaleFactor);
                        Complex z = new Complex(c.Real, c.Imaginary);
    
                        //用简单的逃逸时间算法进行迭代
                        int iteration = 0;
                        while (z.Magnitude < 2 && iteration < maxIterationCount)
                        {
                            z = (z * z) + c;
                            iteration++;
                        }
    
                        // 基于概率的设置像素的阴影
                        byte grayScaleValue = Convert.ToByte(255 - 255.0 * iteration / maxIterationCount);
                        result[resultIndex++] = grayScaleValue; // Green value of pixel
                        result[resultIndex++] = grayScaleValue; // Blue value of pixel
                        result[resultIndex++] = grayScaleValue; // Red value of pixel
                        result[resultIndex++] = 255;            // Alpha value of pixel
                    }
                }
    
                return result;
            }


    显示结果 :

    第二个按钮的 单击事件:

    //用户选取文件后,通过 SetSource() 方法进行赋值
     private async void LoadImageUsingSetSource_Click(object sender, RoutedEventArgs e)
     {
         
         FileOpenPicker picker = new FileOpenPicker();
         picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
         picker.FileTypeFilter.Add(".png");
         picker.FileTypeFilter.Add(".jpeg");
         picker.FileTypeFilter.Add(".jpg");
         picker.FileTypeFilter.Add(".bmp");
    
         StorageFile file = await picker.PickSingleFileAsync();
    
         if (file != null)
         {
             using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
             {
                 try
                 {
                     await Scenario4WriteableBitmap.SetSourceAsync(fileStream);
                 }
                 catch (TaskCanceledException)
                 {
                     // 如果用户重复点击按钮,从而设置 WriteableBitmap 对象的 Source 属性的操作失败
                 }
             }
         }
     }

    显示截图:

    第三个按钮的 单击事件:

    private async void LoadImageUsingPixelBuffer_Click(object sender, RoutedEventArgs e)
    {
        //这个方法通过把一张图片编码到一个 byte 流中,然后加载到 
        //WriteableBitmap 中,并且把结果复制到一个 WriteableBitmap 的
        //像素的 buffer(缓冲区) 中
        FileOpenPicker picker = new FileOpenPicker();
        picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
        picker.FileTypeFilter.Add(".png");
        picker.FileTypeFilter.Add(".jpeg");
        picker.FileTypeFilter.Add(".jpg");
        picker.FileTypeFilter.Add(".bmp");
    
        StorageFile file = await picker.PickSingleFileAsync();
    
          if (file != null)
        {
            using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
            {
    
                // 异步创建新的 BitmapDecoder 并使用流将其初始化。
                BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);
                
            


    // 缩放图像到大小适当的尺寸 // 包含可应用于像素或位图数据的转换集。 BitmapTransform transform = new BitmapTransform() {
    //
    指定任何转换缩略图的高度(以像素为单位)。 ScaledWidth = Convert.ToUInt32(Scenario4WriteableBitmap.PixelWidth), ScaledHeight = Convert.ToUInt32(Scenario4WriteableBitmap.PixelHeight)}; //使用指定参数异步请求帧的像素数据。 PixelDataProvider pixelData = await decoder.GetPixelDataAsync( BitmapPixelFormat.Bgra8, // WriteableBitmap 使用 BGRA 格式 BitmapAlphaMode.Straight, transform, // EXIF 方向标志被忽略。未执行旋转或翻转操作。 //This sample ignores Exif orientation ExifOrientationMode.IgnoreExifOrientation, // 未执行颜色管理 ColorManagementMode.DoNotColorManage); // 一个包含图像解码数据的数组,可以在显示之前修改 //返回内部存储的像素数据。 byte[] sourcePixels = pixelData.DetachPixelData(); // 打开一个流,并将图像的内容复制到 WriteableBitmap 的像素缓冲区中 using (Stream stream = Scenario4WriteableBitmap.PixelBuffer.AsStream()) { //将字节序列异步写入当前流,并将流的当前位置向前移动写入的字节数。 await stream.WriteAsync(sourcePixels, 0, sourcePixels.Length); } } // 重新绘制这个 WriteableBitmap 对象 //请求绘制或重绘整个位图。 Scenario4WriteableBitmap.Invalidate(); } }


    显示结果和 上一个方法的结果相同。

  • 相关阅读:
    文件权限
    函数指针
    位操作
    宏定义
    GNU gcc常用编译选项
    SHELL编程(六)---------数组和函数
    26.使用中间件的方式包装日志输出
    25.最基本的日志输出方式,内置日志包使用
    24.把熔断器整合到我们的客户端代码中(初步)
    23.熔断器学习,熔断器的三种状态,状态获取
  • 原文地址:https://www.cnblogs.com/hebeiDGL/p/2771988.html
Copyright © 2011-2022 走看看