У меня возникла проблема, когда я показываю изображение в .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>
Есть ли способ сохранить размер изображения пропорциональным реальному размеру?
Пожалуйста, прочитайте документы на Aspect
Обратите внимание, что проблема здесь в том, что изображению дается больше места по вертикали, чем ему нужно. Это похоже на layout проблему, а не Aspect проблему. Я не понимаю, почему VerticalStackLayout может придать изображению большую высоту, чем необходимо. Предложения для ОП? @copang, это все еще происходит, если удалить ScrollView? (Я понимаю, что вам может понадобиться ScrollView, но это ценный тест для определения причины.)
Вы можете попробовать установить запрос ширины или высоты для изображения.
@ToolmakerSteve, я пытался удалить ScrollView и даже StackLayout, но результат тот же
@LiqunShen-MSFT, я стараюсь не задавать ширину и высоту, потому что ищу способ, чтобы представление автоматически вычисляло размер. Раньше я использовал решение здесь social.msdn.microsoft.com/Forums/en-US/…, но оно не работает с .NET MAUI
Я внес некоторые изменения:
Ниже приведен мой код,
Для 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, было бы здорово, если бы он мог сам определять соотношение.
Да, можно, но с использованием кода платформы. Я скоро обновлю свой ответ.
@ToolmakerSteve Большое спасибо за ваше предложение. Я не учел этот момент и теперь пытаюсь получить ширину и высоту с помощью кода платформы.
@copang Я обновил свой ответ, чтобы получить ширину и высоту изображения, а затем коэффициент подсчета. Вы могли бы попробовать.
О какой ОС идет речь? Кроме того, как вы думаете, это функция "AspectFit"?