簡體   English   中英

如何在UWP應用程序中同步獲取圖像的尺寸?

[英]How do I get the dimensions of an image synchronously in a UWP app?

我想在OnLoaded()方法中顯示圖像之前獲取圖像的尺寸。 我想同步(不是異步)這樣做,因為我需要在程序繼續之前知道圖像的尺寸。 我正在制作一個映射程序,其中背景圖像的坐標,比例和平移偏移很重要,並且都取決於從應用程序的最開始就知道圖像的尺寸。

我已經閱讀了大部分有關StorageFile,SoftwareBitmap和異步方法調用的msdn文檔,並嘗試了許多我在網上找到的方法,但沒有成功。 https://msdn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-universal-windows-platform-apps

https://msdn.microsoft.com/en-us/windows/uwp/threading-async/call-asynchronous-apis-in-csharp-or-visual-basic

基本上我正在尋找一個同步c#函數,它接受一個圖像文件的uri並返回一個包含維度的Point。 即公共點getImageDimensions(Uri u){...}

這個功能很容易在Android應用程序中實現,我不明白為什么它在UWP應用程序中如此困難。

如果需要,我可以提供更多詳細信息,提前感謝。

我用以下代碼得到以下錯誤:
拋出異常:App1.exe中的“System.Exception”
拋出異常:mscorlib.ni.dll中的“System.AggregateException”

App1.xaml.cs

using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Shapes;

namespace App1
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += OnLoaded;

            Point p = Task.Run(() => getImageDimensions("ms-appx:///Assets/NewSpaceBackground.png")).Result;
            Debug.WriteLine("p.X: " + p.X + " p.Y: " + p.Y);
        }

        void OnLoaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
        {
            Rectangle backgroundRect1 = new Rectangle();
            ImageBrush imgBrushBackground1 = new ImageBrush();
            imgBrushBackground1.ImageSource = new BitmapImage(new Uri(@"ms-appx:///Assets/NewSpaceBackground.png"));
            backgroundRect1.Fill = imgBrushBackground1;
            //backgroundMap.Add(backgroundRect1);
        }

        public async Task<Point> getImageDimensions(string strURI)
        {
            Point p;
            StorageFile photo;
            try
            {
                var uri = new Uri(strURI);
                photo = await StorageFile.GetFileFromApplicationUriAsync(uri);
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.StackTrace);
                return p;
            }
            //read in the bitmap stream
            IRandomAccessStream stream = await photo.OpenAsync(FileAccessMode.Read);
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
            SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync();

            //convert the image to a bitmap
            SoftwareBitmap softwareBitmapBGR8 = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
            SoftwareBitmapSource bitmapSource = new SoftwareBitmapSource();
            await bitmapSource.SetBitmapAsync(softwareBitmapBGR8);

            //print out the dimensions
            Debug.WriteLine(softwareBitmapBGR8.PixelWidth + " " + softwareBitmapBGR8.PixelHeight);
            p.X = softwareBitmapBGR8.PixelWidth;
            p.Y = softwareBitmapBGR8.PixelHeight;

            return p;
        }
    }
}

我想在OnLoaded()方法中顯示圖像之前獲取圖像的尺寸。 我想同步(不是異步)這樣做,因為我需要在程序繼續之前知道圖像的尺寸。

當您想在構造函數中調用異步函數時會出現一些問題,有關詳細信息,請參閱Stephen Cleary的博客: Async OOP 2:Constructors

在UWP中,您可以在Page.OnNavigatedTo方法中放置頁面初始化代碼( getImageDimensions和顯示圖像的代碼),並在其中使用await

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    Point p = await getImageDimensions("ms-appx:///Assets/NewSpaceBackground.png");
    Debug.WriteLine("p.X: " + p.X + " p.Y: " + p.Y);

    Rectangle backgroundRect1 = new Rectangle();
    ImageBrush imgBrushBackground1 = new ImageBrush();
    imgBrushBackground1.ImageSource = new BitmapImage(new Uri(@"ms-appx:///Images/image03.jpg"));
    backgroundRect1.Fill = imgBrushBackground1;
    ...
}

更新:

您會建議使用更簡單,同步的方式來獲取尺寸嗎?

大多數文件相關操作都是異步的,用戶可以使用/不使用await選擇同步或異步操作。

確實有一種簡單的方法來獲得圖像的維度:

StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///images/image01.png"));
var properties=await file.Properties.GetImagePropertiesAsync();
var width = properties.Width;
var height = properties.Height;

您可以將它加載到System.Drawing.Image中,而不是將其流式傳輸到Bitmap中嗎?

System.Drawing.Image img = System.Drawing.Image.FromStream(myStream);

然后,您可以訪問System.Drawing.Image的Size屬性,該屬性可以為您提供所需的內容,以及輕松訪問大小調整。 如果內存服務,所有這些都可以在.NET Core和UWP中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM