.NET MAUI Изображение неправильного размера

У меня возникла проблема, когда я показываю изображение в .NET MAUI, размер изображения всегда больше, чем он есть на самом деле (синяя часть на изображении ниже).

Скриншот

Мой код выглядит следующим образом:

<Grid>
    <ScrollView>
        <VerticalStackLayout>
            <Image Source = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                    Aspect = "AspectFit" BackgroundColor = "Blue">
                <Image.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </Image.Margin>
            </Image>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Есть ли способ сохранить размер изображения пропорциональным реальному размеру?

О какой ОС идет речь? Кроме того, как вы думаете, это функция "AspectFit"?

H.A.H. 16.02.2023 11:26

Пожалуйста, прочитайте документы на Aspect

Jason 16.02.2023 12:56

Обратите внимание, что проблема здесь в том, что изображению дается больше места по вертикали, чем ему нужно. Это похоже на layout проблему, а не Aspect проблему. Я не понимаю, почему VerticalStackLayout может придать изображению большую высоту, чем необходимо. Предложения для ОП? @copang, это все еще происходит, если удалить ScrollView? (Я понимаю, что вам может понадобиться ScrollView, но это ценный тест для определения причины.)

ToolmakerSteve 16.02.2023 21:33

Вы можете попробовать установить запрос ширины или высоты для изображения.

Liqun Shen-MSFT 17.02.2023 06:22

@ToolmakerSteve, я пытался удалить ScrollView и даже StackLayout, но результат тот же

copang 17.02.2023 09:45

@LiqunShen-MSFT, я стараюсь не задавать ширину и высоту, потому что ищу способ, чтобы представление автоматически вычисляло размер. Раньше я использовал решение здесь social.msdn.microsoft.com/Forums/en-US/…, но оно не работает с .NET MAUI

copang 17.02.2023 09:51
Laravel с Turbo JS
Laravel с Turbo JS
Turbo - это библиотека JavaScript для упрощения создания быстрых и высокоинтерактивных веб-приложений. Она работает с помощью техники под названием...
Типы ввода HTML: Лучшие практики и советы
Типы ввода HTML: Лучшие практики и советы
HTML, или HyperText Markup Language , является стандартным языком разметки, используемым для создания веб-страниц. Типы ввода HTML - это различные...
Аутсорсинг разработки PHP для индивидуальных веб-решений
Аутсорсинг разработки PHP для индивидуальных веб-решений
Услуги PHP-разработки могут быть экономически эффективным решением для компаний, которые ищут высококачественные услуги веб-разработки по доступным...
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Слишком много useState? Давайте useReducer!
Слишком много useState? Давайте useReducer!
Современный фронтенд похож на старую добрую веб-разработку, но с одной загвоздкой: страница в браузере так же сложна, как и бэкенд.
Узнайте, как использовать теги &lt;ul&gt; и &lt;li&gt; для создания неупорядоченных списков в HTML
Узнайте, как использовать теги <ul> и <li> для создания неупорядоченных списков в HTML
HTML предоставляет множество тегов для структурирования и организации содержимого веб-страницы. Одним из наиболее часто используемых тегов для...
0
6
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я внес некоторые изменения:

  1. Я попытался использовать привязку данных способом MVVM.
  2. Я попытался подсчитать соотношение изображений, используя код платформы.

Ниже приведен мой код,

Для MainPage.xaml разница в том, что я использую привязку данных для свойства Source и AspectRatio изображения, которое будет заявлено в MainPageVeiwModel.

<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source = "{Binding ImageUrl}"
                     AspectRatio = "{Binding AspectRatio}" Aspect = "AspectFit" BackgroundColor = "Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Для пользовательского элемента управления AspectImage разница в том, что я изменил свойство AspectRatio на Bindable, поскольку мы используем привязку для этого свойства. Подробнее Привязываемые свойства.

public class AspectImage : Image
{
    public static readonly BindableProperty AspectRatioProperty = BindableProperty.Create("AspectRatio", typeof(double), typeof(AspectRatioContainer), null);

    public double AspectRatio
    {
        get { return (double)GetValue(AspectRatioProperty); }
        set { SetValue(AspectRatioProperty, value); }
    }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}

Для MainPageViewModel мы добавляем свойство AspectRatio и ImageUrl для настраиваемого элемента управления и подсчета AspectRatio.

public class MainPageViewModel
{
    public string ImageUrl { get; set; }
    public double AspectRatio { get; set; }

    public MainPageViewModel()
    {
        ImageUrl = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg";

        AspectRatio = CountAspectRatio(ImageUrl);
    }

    private double CountAspectRatio(string imageUrl)
    {
        var service = new GetImageSizeService();
        Size imageSize = service.GetImageSize(imageUrl);
        return imageSize.Height / imageSize.Width;
    }
}

Из приведенного выше кода в MainPageViewModel мы подсчитываем AspectRatio по коду платформы вызова. Если вы не знакомы с ним, я рекомендую сначала этот учебник: Как написать код для конкретной платформы в .NET MAUI.

Чтобы внедрить код платформы в Maui (в Xamarin можно использовать DependencyService):

Во-первых, в папке Project создайте новый разделяемый класс, назовем его GetImageSizeService:

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file);
}

Затем создайте еще один частичный класс в папке Platforms/iOS, также назовите его GetImageSizeService. Обратите внимание, что пространство имен должно быть таким же, как у файла выше.

public partial class GetImageSizeService
{
    public partial Size GetImageSize(string file)
    {
        NSData data = NSData.FromUrl(NSUrl.FromString(file));

        UIImage image = UIImage.LoadFromData(data);
        return new Size((double)image.Size.Width, (double)image.Size.Height);
    }
}

Затем в MainPageViewModel мы просто вызываем эту службу и считаем AspectRatio.

=========================== Первый пост=============

Добавленная вами ссылка вдохновила меня. И если я правильно понял ваш вопрос, вы можете попробовать следующий код, который сработал для меня:

Создайте пользовательский элемент управления AspectImage, который устанавливает соотношение сторон для ширины и высоты.

public class AspectImage : Image
{
    public double AspectRatio { get; set; }

    public AspectImage()
    {
        SizeChanged += HandleSizeChanged;
    }

    private void HandleSizeChanged(object sender, EventArgs e)
    {
        if (this.Width > 0 && AspectRatio > 0)
        {
            var desiredHeightRequest = this.Width * AspectRatio;           
            if ((int)desiredHeightRequest != (int)HeightRequest)
            {
                this.HeightRequest = (int)desiredHeightRequest;
                InvalidateMeasure();
            }
        }
    }
}

Для xaml используйте AspectImage. Здесь соотношение сторон кажется 4/9 Примерно равно 0,44

<Grid>
    <ScrollView>
        <VerticalStackLayout>                          
            <a:AspectImage Source = "https://cdn-5e5150f5f911c807c41ebdc8.closte.com/wp-content/uploads/IoT-development-kit-article-banner-scaled-900x400.jpg"
                     AspectRatio = "0.44" Aspect = "AspectFit" BackgroundColor = "Blue">
                <a:AspectImage.Margin>
                    <OnIdiom Phone = "10" Tablet = "20" Desktop = "20"/>
                </a:AspectImage.Margin>
            </a:AspectImage>
        </VerticalStackLayout>
    </ScrollView>
</Grid>

Надеюсь, это сработает для вас.

Можно ли запросить у источника изображения его ширину и высоту? Избавится от необходимости вручную устанавливать соотношение сторон.

ToolmakerSteve 17.02.2023 19:03

Он работает именно так, как я ожидал, большое спасибо. И, как сказал @ToolmakerSteve, было бы здорово, если бы он мог сам определять соотношение.

copang 18.02.2023 03:39

Да, можно, но с использованием кода платформы. Я скоро обновлю свой ответ.

Liqun Shen-MSFT 18.02.2023 04:38

@ToolmakerSteve Большое спасибо за ваше предложение. Я не учел этот момент и теперь пытаюсь получить ширину и высоту с помощью кода платформы.

Liqun Shen-MSFT 18.02.2023 05:16

@copang Я обновил свой ответ, чтобы получить ширину и высоту изображения, а затем коэффициент подсчета. Вы могли бы попробовать.

Liqun Shen-MSFT 18.02.2023 05:18

Другие вопросы по теме