Xamarin Forms Ширина заливки изображения с соответствующим аспектом
Вот xaml (изображение в stacklayout). Все логично: я установил Aspect для AspectFit и HorizontalOptions в FillAndExpand. Ширина изображения должна заполнять ширину stacklayout. Высота должна быть рассчитана для изображения Aspect.
<Image BackgroundColor="Fuchsia"
Aspect="AspectFit"
Source="{Binding GroupLogo}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"/>
Он заполняет ширину, но не хочет рисовать полную ширину изображения. Почему?
![введите описание изображения здесь]()
Ответы
Ответ 1
AspectFit
делает то, что он говорит на олове, он поместит все изображение в представление, которое может оставить части представления пустыми. Прямо из документации Xamarin:
Масштабируйте изображение, чтобы оно соответствовало виду. Некоторые части могут быть пустыми (буквенный бокс).
То, что вы ищете, это AspectFill
, который масштабирует изображение в соответствии с:
Масштабируйте изображение, чтобы заполнить представление. Некоторые части могут быть обрезаны, чтобы заполнить представление.
Если вы пытаетесь получить представление изображения как высоту изображения, я бы предложил добавить HeightRequest
к высоте изображения. По-моему, элементы управления изображением, по моему опыту, автоматически не масштабируются в Xamarin, поскольку встроенные элементы управления также не поддерживают это по умолчанию.
Ссылка
Ответ 2
У меня была аналогичная проблема. Я хотел заполнить ширину и высоту StackLayout, когда это возможно, но без обрезки фактического изображения. Ответы здесь помогли мне найти правильный путь. Вот что сработало для меня:
<Grid
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
>
<Image
x:Name="photo"
Aspect="AspectFit"
/>
</Grid>
Возможно, это будет полезно для кого-то.
Разъяснение:
HorizontalOptions и VerticalOptions имеют значение FillAndExpand, поэтому высота и ширина сетки настраиваются для заполнения родителя, в этом случае это Stacklayout. Изображение является дочерним элементом сетки, поэтому оно преобразуется в соответствии с родительским (мы не предоставляли никаких дополнительных параметров изображению).
Аспект изображения установлен в AspectFit, так что изображение будет соответствовать представлению (в данном случае Grid), а также сохранить его отношения.
Таким образом, если изображение находится в портретном режиме, но слишком узкое, оно заполняет высоту сетки (StackLayout), но не заполняет ширину, чтобы сохранить свои отношения и не обрезаться сверху или снизу.
Если изображение находится в ландшафтном режиме, оно заполняет ширину сетки (StackLayout), но не заполняет высоту, чтобы сохранить ее отношения и не обрезаться слева или справа.
Ответ 3
Как я не нашел рабочего примера. Это прекрасно работает для меня:
<Grid VerticalOptions="FillAndExpand">
<Image Source="{Binding MyImageSrc}" Aspect="AspectFill" />
</Grid>
Ответ 4
Aspect = "AspectFit" используется для размещения вашего изображения внутри макета, оно может оставить пространство, если изображения маленькие. Aspect = "AspectFill" используется для размещения вашего изображения внутри макета, и оно растянет ваше изображение, чтобы занять все пространство, и не оставит места, либо ваше изображение будет маленьким по сравнению с вашим родительским пространством макета. Таким образом, вы должны использовать AspectFill вместо AspectFit.
Ответ 5
Попробуйте включить изображение внутри сетки, например:
<grid>
<image></image>
</grid>
Иногда, когда у меня есть изображение, которое не изменяется правильно, включение его в сетку решает проблему.
Ответ 6
Попробуйте использовать CachedImage
из FFImageLoading Пакет NuGet
MyPage.xaml
<StackLayout HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Padding="0">
<ff:CachedImage Source="{Binding GroupLogo}"
HorizontalOptions="Fill"
VerticalOptions="Fill"
Aspect="Fill"
DownsampleToViewSize="True"/>
</StackLayout>
Это приведет к тому, что изображение попытается горизонтально заполнить контейнер и автоматически сгенерировать ширину при сохранении ее аспекта.
Добавьте эту строку кода в MainActivity.xaml после global::Xamarin.Forms.Forms.Init(this, bundle);
CachedImageRenderer.Init(true);
Пример можно найти здесь
Ответ 7
heightrequest из stacklayout должен быть либо StartAndExpand, либо FillAndExpand или EndAndExpand, чтобы автоматически регулировать высоту
Ответ 8
Это требует пользовательского рендеринга для обеих платформ. Создайте FillScreenImageRenderer, который наследуется от ImageRenderer.
<local:FillScreenImage Source="{ImageSource}"></local:FillScreenImage>
Код ниже растягивается на весь экран. Вы можете настроить границы представления так, чтобы они подходили к чему угодно, например, в вашем случае это родительское представление.
IOS:
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
UIGraphics.BeginImageContext(UIScreen.MainScreen.Bounds.Size);
Control.Image.Draw(UIScreen.MainScreen.Bounds);
var dest = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
Control.Image = dest;
}
Android:
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
var display = ((Activity)Context).WindowManager.DefaultDisplay;
var b = ((BitmapDrawable)Control.Drawable).Bitmap;
Bitmap bitmapResized = Bitmap.CreateScaledBitmap(b, display.Width, display.Height, false);
Control.SetImageDrawable(new BitmapDrawable(Resources, bitmapResized));
}