Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6514735
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Android平台

2018-08-15 21:49:25

嵌入资源
通过Internet访问位图很方便,但有时候并不是最佳选择。该过程需要互联网连接,确保位图未被移动,并有一段时间下载。为了快速且有保证地访问位图,它们可以直接绑定到应用程序中。
如果需要访问非特定于平台的映像,则可以将位图作为嵌入资源包含在共享的可移植类库项目中,并使用ImageSource.From?Resource方法访问它们。 ResourceBitmapCode解决方案演示了如何执行此操作。
此解决方案中的ResourceBitmapCode PCL项目有一个名为Images的文件夹,它包含两个位图,名为ModernUserInterface.jpg(一个非常大的位图)和ModernUserInterface256.jpg(相同的图片,但宽度为256像素)。
将任何类型的嵌入资源添加到PCL项目时,请确保将资源的构建操作设置为EmbeddedResource。这很关键。
在代码中,将Image元素的Source属性设置为从静态ImageSource.FromResource方法返回的ImageSource对象。此方法需要资源ID。 resource ID包括程序集名称后跟句点,然后是文件夹名称后跟一个otherperiod,然后是文件名,其中包含文件扩展名的另一个句点。对于此示例,用于访问ResourceBitmapCode程序中两个位图中较小位图的资源ID为:
ResourceBitmapCode.Images.ModernUserInterface256.jpg
此程序中的代码引用较小的位图,并将Image元素上的HorizontalOptions和VerticalOptions设置为Center:

点击(此处)折叠或打开

  1. public class ResourceBitmapCodePage : ContentPage
  2. {
  3.     public ResourceBitmapCodePage()
  4.     {
  5.         Content = new Image
  6.         {
  7.             Source = ImageSource.FromResource(
  8.                         "ResourceBitmapCode.Images.ModernUserInterface256.jpg"),
  9.             VerticalOptions = LayoutOptions.Center,
  10.             HorizontalOptions = LayoutOptions.Center
  11.         };
  12.     }
  13. }

如您所见,此实例中的位图未展开以填充页面:

如果符合以下情况,则不会拉伸位图以填充其容器:

  • 它小于容器,并且
  • 未设置Image元素的VerticalOptions和HorizontalOptions属性
    填充,或者如果Image是StackLayout的子级。

如果注释掉VerticalOptions和HorizontalOptions设置,或者引用大位图(文件名末尾没有“256”),图像将再次拉伸以填充容器。
如果未展开位图以适合其容器,则必须以特定大小显示该位图。那个大小是多少?
在iOS和Android上,位图以像素大小显示。换句话说,通过位图的像素和视频显示的像素之间的一对一映射来渲染位图。用于这些屏幕截图的iPhone 6模拟器的屏幕宽度为750像素,您可以看到位图的256像素宽度约为宽度的三分之一。这里的Android手机是Nexus 5,其像素宽度为1080,位图大约是宽度的四分之一。
但是,在Windows运行时平台上,位图显示在与设备无关的单元中 - 在此示例中,为256个与设备无关的单元。用于这些屏幕截图的诺基亚Lumia 925的像素宽度为768,与iPhone 6大致相同。但是,这款Windows 10 Mobile手机在独立于设备的设备中的屏幕宽度为341,您可以看到ren?dered位图比其他平台宽得多。
有关调整位图大小的讨论将在下一节继续讨论。
您如何引用从XAML存储为嵌入资源的位图?不幸的是,没有ResourceImageSource类。如果有,您可能会尝试在Image.Source标记之间在XAML中实例化该类。但那不是一个选择。
您可以考虑使用x:FactoryMethod来调用ImageSource.FromResource,但这不起作用。正如当前实现的那样,ImageSource.FromResource方法要求位图资源与调用该方法的代码位于同一程序集中。当您使用x:FactoryMethod调用ImageSource.FromResource时,将从Xamarin.Forms.Xaml程序集进行调用。
什么是有效的是一个非常简单的XAML标记扩展。这是一个名为StackedBitmap的项目中的一个:

点击(此处)折叠或打开

  1. namespace StackedBitmap
  2. {
  3.     [ContentProperty ("Source")]
  4.     public class ImageResourceExtension : IMarkupExtension
  5.     {
  6.         public string Source { get; set; }
  7.         public object ProvideValue (IServiceProvider serviceProvider)
  8.         {
  9.             if (Source == null)
  10.                 return null;
  11.             return ImageSource.FromResource(Source);
  12.         }
  13.     }
  14. }
ImageResourceExtension有一个名为Source的属性,您可以将其设置为资源ID。 ProvideValue方法只使用Source属性调用ImageSource.FromResource。 对于单属性标记扩展常见,Source也是该类的content属性。 这意味着当您使用大括号语法进行XAML标记扩展时,您不需要显式包含“Source =”。
但请注意:您无法将此ImageResourceExtension类移动到诸如Xama?rin.FormsBook.Toolkit之类的库中。 该类必须是包含要加载的嵌入式源的同一程序集的一部分,通常是应用程序的可移植类库。
这是StackedBitmap项目中的XAML文件。 Image元素与StackLayout共享两个Label元素:

点击(此处)折叠或打开

  1. <ContentPage xmlns=""
  2.              xmlns:x=""
  3.              xmlns:local="clr-namespace:StackedBitmap "
  4.              x:Class="StackedBitmap.StackedBitmapPage">
  5.  
  6.     <StackLayout>
  7.         <Label Text="320 x 240 Pixel Bitmap"
  8.                FontSize="Medium"
  9.                VerticalOptions="CenterAndExpand"
  10.                HorizontalOptions="Center" />
  11.  
  12.         <Image Source="{local:ImageResource StackedBitmap.Images.Sculpture_320x240.jpg}"
  13.                BackgroundColor="Aqua"
  14.                SizeChanged="OnImageSizeChanged" />
  15.         <Label x:Name="label"
  16.                FontSize="Medium"
  17.                VerticalOptions="CenterAndExpand"
  18.                HorizontalOptions="Center" />
  19.     </StackLayout>
  20. </ContentPage>
本地前缀是指StackedBitmap程序集中的StackedBitmap命名空间。 Image元素的Source属性设置为ImageResource标记扩展,它引用存储在PCL项目的Images文件夹中的位图并标记为EmbeddedResource。 位图宽320像素,高240像素。 Image还设置了BackgroundColor属性; 这将允许我们在StackLayout中查看Image的整个大小。
Image元素的SizeChanged事件设置为代码隐藏文件中的处理程序:

点击(此处)折叠或打开

  1. public partial class StackedBitmapPage : ContentPage
  2. {
  3.     public StackedBitmapPage()
  4.     {
  5.         InitializeComponent();
  6.     }
  7.     void OnImageSizeChanged(object sender, EventArgs args)
  8.     {
  9.         Image image = (Image)sender;
  10.         label.Text = String.Format("Render size = {0:F0} x {1:F0}",
  11.                                    image.Width, image.Height);
  12.    }
  13. }
Image元素的大小由StackLayout垂直约束,因此位图以其像素大小(在iOS和Android上)和在Windows Phone上与设备无关的单位显示。 Label以与设备无关的单位显示Image元素的大小,这些单元在每个平台上都有所不同:

底部Label显示的Image元素的宽度包括aqua背景,并且等于设备无关单元中页面的宽度。 您可以使用Fill或As?pectFill的Aspect设置来使位图填充整个aqua区域。
如果您希望Image元素的大小与设备独立单元中的渲染位图大小相同,则可以将Image的HorizontalOptions属性设置为Fill的默认值以外的值:

点击(此处)折叠或打开

  1. <Image Source="{local:ImageResource StackedBitmap.Images.Sculpture_320x240.jpg}"
  2.        HorizontalOptions="Center"
  3.        BackgroundColor="Aqua"
  4.        SizeChanged="OnImageSizeChanged" />
现在,底部Label仅显示渲染位图的宽度。 Aspect支架的设置无效:

让我们将这个渲染的图像大小称为其自然大小,因为它基于正在显示的位图的大小。
iPhone 6的像素宽度为750像素,但正如您在第5章中运行WhatSize程序时发现的那样,应用程序感知屏幕宽度为375.设备有两个像素?独立单元,因此位图的宽度为显示320像素,宽度为160个单位。
Nexus 5的像素宽度为1080,但应用程序感知宽度为360,因此与设备无关的单元有三个像素,因为107个单元的图像宽度确认。
在iOS和Android设备上,当以自然大小显示位图时,位图的像素与显示器的像素之间存在一对一的映射。但是,在Windows运行时设备上,情况并非如此。用于这些屏幕截图的诺基亚Lumia 925的像素宽度为768.运行Windows 10 Mobile操作系统时,设备独立单元有2.25像素,因此应用程序感知屏幕宽度为341。但320× 240像素位图以320×240个与设备无关的单元的大小显示。
当您从各个平台项目访问位图时,Windows运行时和其他两个平台之间的这种不一致实际上是有益的。正如您将看到的,iOS和Android包含一项功能,可让您为不同的设备分辨率提供不同大小的位图。在效果上,这允许您在与设备无关的单元中指定位图大小,这意味着Windows设备与这些方案一致。
但是当使用与平台无关的位图时,您可能希望在所有三个平台上确定位图的大小,这需要更深入地了解主题。
阅读(4871) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~