中的影像 Xamarin.Forms

Download Sample 下載範例

您可以透過 Xamarin.Forms跨平台共用影像,它們可以特別針對每個平台載入,也可以下載以供顯示。

影像是應用程式流覽、可用性和商標的重要部分。 Xamarin.Forms 應用程式必須能夠跨所有平台共用映像,但也可能會在每個平台上顯示不同的影像。

圖示和啟動顯示畫面也需要平臺特定影像;這些必須根據每個平台進行設定。

顯示影像

Xamarin.Forms 會使用檢視 Image 在頁面上顯示影像。 它有數個重要屬性:

  • SourceImageSource- 將影像設定為要顯示的實例,可以是 File、Uri 或 Resource。
  • Aspect - 如何調整其顯示範圍內的影像大小(無論是伸展、裁剪或信箱)。

ImageSource 實體可以使用每種影像來源類型的靜態方法來取得:

  • FromFile - 需要可在每個平臺上解析的檔名或檔案路徑。
  • FromUri - 需要 Uri 物件,例如 new Uri("http://server.com/image.jpg") .
  • FromResource - 需要資源標識碼給內嵌在應用程式或 .NET Standard 連結庫專案中的映像檔,並搭配 Build Action:EmbeddedResource
  • FromStream - 需要提供影像數據的數據流。

屬性 Aspect 會決定如何縮放影像以符合顯示區域:

  • Fill - 延展影像以完整且完全填滿顯示區域。 這可能會導致影像扭曲。
  • AspectFill - 裁剪影像,使其填滿顯示區域,同時保留外觀(亦即不會失真)。
  • AspectFit - 信件箱影像(如有必要),讓整個影像符合顯示區域,並將空白空間新增至頂端/底部或側邊,視影像寬或高而定。

您可以從本機檔案、內嵌資源下載或從數據流載入影像。 此外,檢視可以藉由指定 物件中的FontImageSource字型圖示數據來顯示Image字型圖示。 如需詳細資訊,請參閱字型指南中的顯示字型圖示。

本機影像

圖像檔可以新增至每個應用程式專案,並從共用程式代碼參考 Xamarin.Forms 。 當影像是平台專用的 (例如,在不同平台上使用不同的解析度) 或屬於略微不同的設計時,就需要這種影像散發方法。

若要在所有應用程式中使用單一影像, 每個平臺上都必須使用相同的檔名,而且它應該是有效的 Android 資源名稱(也就是只允許小寫字母、數位、底線和句點)。

  • iOS - 因為 iOS 9 是使用 資產類別目錄映像集,因此管理及支援映像的慣用方式,其應該包含支援各種裝置和應用程式縮放因數所需之映像的所有版本。 如需詳細資訊,請參閱 將映像新增至資產類別目錄映射集
  • Android - 使用建置動作將影像放在資源/可繪製的目錄中:AndroidResource。 也可以提供影像的高和低 DPI 版本(在適當命名的資源子目錄中,例如 drawable-ldpi、drawable-hdpidrawable-xhdpi)。
  • 通用 Windows 平台 (UWP) - 根據預設,映像應該放在應用程式的根目錄中,並具有建置動作:內容。 或者,映像可以放在不同的目錄中,然後以平臺特定方式指定。 如需詳細資訊,請參閱 Windows 上的預設映像目錄。

重要

在 iOS 9 之前,映像通常會放在 [資源] 資料夾中,並具有建置動作:BundleResource 不過,在 iOS 應用程式中使用影像的這個方法已被 Apple 取代。 如需詳細資訊,請參閱 影像大小和檔名

遵守這些檔案命名和放置規則,可讓下列 XAML 在所有平臺上載入和顯示影像:

<Image Source="waterfront.jpg" />

對等的 C# 程式代碼如下所示:

var image = new Image { Source = "waterfront.jpg" };

下列螢幕快照顯示在每個平台上顯示本機影像的結果:

Sample application displaying a local image

如需更多彈性, Device.RuntimePlatform 屬性可用來選取某些或所有平臺的不同映像檔或路徑,如下列程式代碼範例所示:

image.Source = Device.RuntimePlatform == Device.Android
                ? ImageSource.FromFile("waterfront.jpg")
                : ImageSource.FromFile("Images/waterfront.jpg");

重要

若要在所有平臺上使用相同的映像檔名,名稱在所有平臺上都必須有效。 Android 可繪製專案具有命名限制 –只允許小寫字母、數位、底線和句點,而且為了跨平臺相容性,其他所有平臺上也必須遵循此限制。 範例檔名 waterfront.png 遵循規則,但無效檔名的範例包括 “water front.png”、“WaterFront.png”、“water-front.png” 和 “wåterfront.png”。

原生解析度(視網膜和高 DPI)

iOS、Android 和 UWP 包含不同映射解析度的支援,其中操作系統會根據裝置的功能在運行時間選擇適當的映像。 Xamarin.Forms 會使用原生平臺的 API 來載入本機映像,因此如果檔案的名稱正確且位於專案中,它會自動支援替代解析度。

管理映像的慣用方式,因為 iOS 9 是針對適當資產類別目錄映射集所需的每個解析度拖曳影像。 如需詳細資訊,請參閱 將映像新增至資產類別目錄映射集

在 iOS 9 之前,影像的 retina 版本可以放在 Resources 資料夾中 - 在擴展名之前,使用@2x或@3x後綴的解析度的兩次和三倍。 myimage@2x.png 不過,在 iOS 應用程式中使用影像的這個方法已被 Apple 取代。 如需詳細資訊,請參閱 影像大小和檔名

Android 替代解析度影像應該放在 Android 專案中特別命名的目錄中 ,如下列螢幕快照所示:

Android multiple-resolution image location

UWP 映射檔名稱可以在擴展名之前加上 後綴.scale-xxx,其中 xxx 是套用至資產的縮放百分比,例如myimage.scale-200.png。 然後,您可以在程式代碼或 XAML 中參考影像,而不需要縮放修飾詞,例如只 myimage.png。 平台會根據顯示器目前的 DPI 選取最接近的適當資產縮放比例。

顯示影像的其他控制件

某些控制件具有顯示影像的屬性,例如:

  • ButtonImageSource具有屬性,可設定為要顯示在 上的Button點陣圖影像。 如需詳細資訊,請參閱 搭配按鈕使用位圖。

  • ImageButtonSource具有屬性,可設定為要顯示在 中的ImageButton影像。 如需詳細資訊,請參閱 設定影像來源

  • ToolbarItemIconImageSource具有屬性,可設定為從檔案、內嵌資源、URI 或數據流載入的影像。

  • ImageCellImageSource具有屬性,可設定為從檔案、內嵌資源、URI 或數據流擷取的影像。

  • Page. 衍生自 Page 的任何頁面類型都有 IconImageSourceBackgroundImageSource 屬性,可以指派檔案、內嵌資源、URI 或數據流。 在某些情況下,例如 NavigationPage ,當 顯示 ContentPage時,如果平台支援,則會顯示圖示。

    重要

    在 iOS 上 Page.IconImageSource ,屬性無法從資產類別目錄映像集中的影像填入。 相反地,從檔案、內嵌資源、URI 或數據流載入 屬性的圖示影像 Page.IconImageSource

內嵌影像

內嵌映像也會隨附於應用程式(例如本機映像),但不會在每個應用程式的檔案結構中擁有映像複本,映像檔會內嵌在元件中做為資源。 在每一個平臺上使用相同的映射時,建議使用這個散發映射的方法,而且特別適合建立元件,因為映射會與程序代碼配套。

若要在專案中內嵌影像,請以滑鼠右鍵按下以新增專案,然後選取您想要新增的影像/秒。 根據預設,映射會有 [建置動作:無];這必須設定為 [建置動作:EmbeddedResource]。

Set build action to embedded resource

您可以在檔案的 [屬性] 視窗中檢視和變更 [建置動作]。

在此範例中,資源標識碼WorkingWithImages.beach.jpg。 IDE 會使用每個值之間的句點 (.) 將這個項目的預設 命名空間 與檔名串連,以產生此預設值。

如果您將內嵌影像放入專案中的資料夾,則資料夾名稱也會以資源識別碼中的句號 (.) 分隔。 將 beach.jpg 影像移至名為 MyImages 的資料夾會導致資源識別碼 WorkingWithImages.MyImages.beach.jpg

載入內嵌影像的程式代碼只會將 資源識別碼 傳遞至 方法, ImageSource.FromResource 如下所示:

Image embeddedImage = new Image
{
    Source = ImageSource.FromResource("WorkingWithImages.beach.jpg", typeof(MyClass).GetTypeInfo().Assembly)
};

注意

若要支援在 通用 Windows 平台 上以發行模式顯示內嵌影像,必須使用的多載ImageSource.FromResource來指定要搜尋影像的來源元件。

目前沒有資源識別碼的隱含轉換。 相反地,您必須使用 ImageSource.FromResourcenew ResourceImageSource() 來載入內嵌影像。

下列螢幕快照顯示在每個平台上顯示內嵌影像的結果:

Sample application displaying an embedded image

XAML

由於沒有從 stringResourceImageSource的內建類型轉換器,因此 XAML 無法原生載入這些類型的影像。 相反地,您可以使用 XAML 中指定的資源識別碼來寫入簡單的自訂 XAML 標記延伸來載入影像

[ContentProperty (nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
 public string Source { get; set; }

 public object ProvideValue (IServiceProvider serviceProvider)
 {
   if (Source == null)
   {
     return null;
   }

   // Do your translation lookup here, using whatever method you require
   var imageSource = ImageSource.FromResource(Source, typeof(ImageResourceExtension).GetTypeInfo().Assembly);

   return imageSource;
 }
}

注意

若要支援在 通用 Windows 平台 上以發行模式顯示內嵌影像,您必須使用 的多載ImageSource.FromResource來指定要搜尋影像的來源元件。

若要使用此延伸模組,請使用專案的正確命名空間和元件值,將自定義 xmlns 新增至 XAML。 接著可以使用下列語法來設定映射來源: {local:ImageResource WorkingWithImages.beach.jpg}。 完整的 XAML 範例如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<ContentPage
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:local="clr-namespace:WorkingWithImages;assembly=WorkingWithImages"
   x:Class="WorkingWithImages.EmbeddedImagesXaml">
 <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
   <!-- use a custom Markup Extension -->
   <Image Source="{local:ImageResource WorkingWithImages.beach.jpg}" />
 </StackLayout>
</ContentPage>

針對內嵌映像進行疑難解答

偵錯程式碼

因為有時很難了解為何未載入特定映像資源,所以可以暫時將下列偵錯程式代碼新增至應用程式,以協助確認資源已正確設定。 它會將內嵌在指定元件中的所有已知資源輸出至 主控台 ,以協助偵錯資源載入問題。

using System.Reflection;
// ...
// NOTE: use for debugging, not in released app code!
var assembly = typeof(MyClass).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
    System.Diagnostics.Debug.WriteLine("found resource: " + res);
}

內嵌在其他專案中的影像

根據預設, ImageSource.FromResource 方法只會在呼叫 方法的程式代碼 ImageSource.FromResource 相同的元件中尋找影像。 使用上述偵錯程式代碼,您可以藉由將 語句變更 typeof()Type 已知在每個元件中,判斷哪些元件包含特定資源。

不過,搜尋內嵌影像的來源元件可以指定為 方法的 ImageSource.FromResource 自變數:

var imageSource = ImageSource.FromResource("filename.png",
            typeof(MyClass).GetTypeInfo().Assembly);

下載映像

影像可以自動下載以顯示,如下列 XAML 所示:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       x:Class="WorkingWithImages.DownloadImagesXaml">
  <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
    <Label Text="Image UriSource Xaml" />
    <Image Source="https://aka.ms/campus.jpg" />
    <Label Text="campus.jpg gets downloaded from microsoft.com" />
  </StackLayout>
</ContentPage>

對等的 C# 程式代碼如下所示:

var webImage = new Image {
     Source = ImageSource.FromUri(
        new Uri("https://aka.ms/campus.jpg")
     ) };

方法ImageSource.FromUri需要 Uri 物件,並傳回從 Uri讀取的新 UriImageSource

URI 字串也有隱含轉換,因此下列範例也會運作:

webImage.Source = "https://aka.ms/campus.jpg";

下列螢幕快照顯示每個平台上顯示遠端影像的結果:

Sample application displaying a downloaded image

下載的映像快取

UriImageSource也支援快取透過下列屬性設定的已下載映像:

  • CachingEnabled - 是否啟用快取(true 預設為 )。
  • CacheValidityTimeSpan- ,定義映像將儲存在本機的時間長度。

默認會啟用快取,並將映像儲存在本機 24 小時。 若要停用特定映射的快取,請具現化映射來源,如下所示:

image.Source = new UriImageSource { CachingEnabled = false, Uri = new Uri("https://server.com/image") };

若要設定特定的快取期間(例如 5 天)將影像來源具現化,如下所示:

webImage.Source = new UriImageSource
{
    Uri = new Uri("https://aka.ms/campus.jpg"),
    CachingEnabled = true,
    CacheValidity = new TimeSpan(5,0,0,0)
};

內建快取可讓您輕鬆地支援卷動影像清單等案例,您可以在其中設定或系結每個數據格中的影像,並讓內建快取在單元格卷動回檢視時重新載入影像。

動畫 GIF

Xamarin.Forms 包含顯示小型動畫 GIF 的支援。 這可藉由將 Image.Source 屬性設定為動畫 GIF 檔案來完成:

<Image Source="demo.gif" />

重要

雖然 中的 Xamarin.Forms 動畫 GIF 支援包含下載檔的能力,但它不支援快取或串流動畫 GIF。

根據預設,載入動畫 GIF 時,將不會播放。 這是因為 IsAnimationPlaying 屬性會控制動畫 GIF 是否正在播放或停止,預設值為 false。 型 bool別為 的這個屬性是由 BindableProperty 物件所支援,這表示它可以是數據系結的目標,並設定樣式。

因此,載入動畫 GIF 時,在 屬性設定為 true之前IsAnimationPlaying,將不會播放動畫 GIF。 然後將 屬性設定 IsAnimationPlayingfalse,即可停止播放。 請注意,當顯示非 GIF 影像來源時,這個屬性沒有任何作用。

注意

在 Android 上,動畫 GIF 支援需要您的應用程式使用快速轉譯器,如果您已選擇使用舊版轉譯器,將無法運作。 在UWP上,動畫GIF支援需要至少發行 Windows 10 年度更新版(版本 1607)。

圖示和啟動顯示畫面

雖然與檢視無關 Image ,但應用程式圖示和啟動顯示畫面也是專案中影像 Xamarin.Forms 的重要用途。

設定 Xamarin.Forms 應用程式的圖示和啟動顯示畫面會在每個應用程式專案中完成。 這表示為 iOS、Android 和 UWP 產生正確大小的映像。 這些映像應該根據每個平臺的需求來命名及尋找。

圖示

如需建立這些應用程式資源的詳細資訊,請參閱 iOS 使用影像Google 圖示和 UWP 指導方針以取得磚和圖示資產。

此外,檢視可以藉由指定 物件中的FontImageSource字型圖示數據來顯示Image字型圖示。 如需詳細資訊,請參閱字型指南中的顯示字型圖示。

啟動顯示畫面

只有 iOS 和 UWP 應用程式需要啟動畫面(也稱為啟動畫面或預設影像)。

請參閱 Windows 開發人員中心 上 iOS 使用影像啟動顯示畫面的檔。