web-dev-qa-db-fra.com

Xamarin Forms Largeur de remplissage de l'image avec aspect approprié

Voici xaml (une image en stacklayout). Tout est logique: j'ai défini Aspect sur AspectFit et HorizontalOptions sur FillAndExpand. La largeur de l'image doit remplir la largeur de la superposition. La hauteur doit être calculée pour imager l'aspect.

<Image BackgroundColor="Fuchsia"
       Aspect="AspectFit"
       Source="{Binding GroupLogo}"
       HorizontalOptions="FillAndExpand"
       VerticalOptions="FillAndExpand"/>

Il remplit la largeur mais il ne veut pas dessiner l'image sur toute la largeur. Pourquoi?

enter image description here

16
Vorotnyak_Nazar

AspectFit fait ce qu'il dit sur l'étain, il adaptera l'image entière à la vue, ce qui peut laisser des parties de la vue vides. Directement à partir de la documentation de Xamarin:

Redimensionnez l'image pour l'adapter à la vue. Certaines parties peuvent être laissées vides (boîte aux lettres).

Ce que vous recherchez est AspectFill, qui mettra l'image à l'échelle pour l'adapter:

Redimensionnez l'image pour remplir la vue. Certaines parties peuvent être coupées afin de remplir la vue.

Si vous essayez de faire en sorte que la vue de l'image soit à la hauteur de l'image, je vous suggère d'ajouter un HeightRequest à la hauteur de l'image. D'après mon expérience, les contrôles d'image ne semblent pas évoluer automatiquement dans Xamarin, car les contrôles natifs ne semblent pas le prendre en charge par défaut non plus.

Référence

18
Rudi Visser

J'avais un problème similaire. Je voulais remplir la largeur et la hauteur d'un StackLayout lorsque cela était possible mais sans recadrer l'image réelle. Les réponses ici m'ont aidé à trouver la bonne façon. Voici ce qui a fonctionné pour moi:

            <Grid 
                HorizontalOptions="FillAndExpand"
                VerticalOptions="FillAndExpand"
                 >
                <Image
                   x:Name="photo"                         
                   Aspect="AspectFit"                    
                />
            </Grid>

Ce sera peut-être utile à quelqu'un.

Clarification:

HorizontalOptions et VerticalOptions sont avec la valeur FillAndExpand, donc la hauteur et la largeur de la grille sont ajustées pour remplir le parent, dans ce cas que est le Stacklayout. L'image est un enfant de la grille, donc elle se transforme selon le parent (nous n'avons donné aucune option supplémentaire à l'image).

L'aspect de l'image est défini sur AspectFit, de sorte que l'image s'adapte à la vue (dans ce cas, la grille) et conserve également ses ratios.

De cette façon, si l'image est en mode portrait mais trop étroite, elle remplira la hauteur de la grille (StackLayout) mais ne remplira pas la largeur afin de conserver ses ratios et de ne pas être recadrée par dessus ou par dessous.

Si l'image est en mode paysage, elle remplira la largeur de la grille (StackLayout) mais ne remplira pas la hauteur afin de conserver ses proportions et de ne pas être recadrée de gauche ou de droite.

7
Sonia

Comme je n'ai trouvé aucun exemple de travail. Cela fonctionne parfaitement pour moi:

<Grid VerticalOptions="FillAndExpand">
      <Image Source="{Binding MyImageSrc}" Aspect="AspectFill" />
</Grid>
6
kingarthur

Aspect = "AspectFit" utilise pour adapter votre image à l'intérieur de la mise en page, il peut laisser de l'espace si les images sont petites. Aspect = "AspectFill" utilisé pour ajuster votre image à l'intérieur de la mise en page et il étirera votre image pour prendre tout l'espace et ne laissera pas d'espace non plus votre image est petite par rapport à votre espace de mise en page parent. Vous devez donc utiliser AspectFill à la place d'AspectFit.

3
Naveen

Essayez d'utiliser CachedImage de FFImageLoading package NuGet

MaPage.xaml

<StackLayout HorizontalOptions="FillAndExpand"
             VerticalOptions="FillAndExpand"
             Padding="0">
    <ff:CachedImage Source="{Binding GroupLogo}"
                    HorizontalOptions="Fill"
                    VerticalOptions="Fill"
                    Aspect="Fill"
                    DownsampleToViewSize="True"/>
</StackLayout>

Il en résultera une image essayant de remplir horizontalement le conteneur et de générer automatiquement la largeur tout en conservant son aspect.

Ajoutez cette ligne de code à MainActivity.xaml après global::Xamarin.Forms.Forms.Init(this, bundle);

CachedImageRenderer.Init(true);

Un exemple peut être trouvé ici

2
Michael Yuwono

Essayez d'inclure l'image à l'intérieur d'une grille comme:

<grid>
    <image></image>
</grid>

Parfois, lorsque j'ai une image qui n'est pas redimensionnée correctement, l'inclure dans une grille résout le problème.

1
Bjt1776

Cela nécessite un rendu personnalisé pour les deux plates-formes. Créez un FillScreenImageRenderer qui hérite d'ImageRenderer.

<local:FillScreenImage Source="{ImageSource}"></local:FillScreenImage>

Le code ci-dessous s'étire pour s'adapter à tout l'écran. Vous pouvez modifier les limites de la vue pour qu'elles correspondent à tout ce que vous voulez, comme, dans votre cas, la vue parent.

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));
    }
0
Ramon Chan

la demande de superposition de pile doit être StartAndExpand ou FillAndExpand ou EndAndExpand afin d'ajuster automatiquement la hauteur

0
Jay Patel