web-dev-qa-db-ja.com

Xamarin Forms Imageの幅と適切なアスペクト

これがxaml(stacklayoutの画像)です。すべてが論理的です:AspectをAspectFitに、Horizo​​ntalOptionsをFillAndExpandに設定します。画像の幅は、stacklayoutの幅を埋める必要があります。アスペクトを画像化するには、高さを計算する必要があります。

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

それは幅を埋めますが、画像を全幅で描画したくありません。どうして?

enter image description here

16
Vorotnyak_Nazar

AspectFitは、ブリキで言うことを行います。ビュー全体に画像全体が収まり、ビューの一部が空のままになる場合があります。 Xamarinのドキュメントから直接:

ビューに合わせて画像を拡大縮小します。一部の部分は空のままになる場合があります(レターボクシング)。

探しているのはAspectFillです。これにより、画像が収まるようにスケーリングされます。

ビュー全体に画像を拡大縮小します。ビューを埋めるために、一部の部分がクリップされる場合があります。

画像ビューを画像の高さにしようとしている場合は、HeightRequestを画像の高さに追加することをお勧めします。私の経験では、画像コントロールはXamarinで自動的にスケーリングされないようです。これは、ネイティブコントロールもデフォルトではサポートしていないようだからです。

参照

18
Rudi Visser

同様の問題がありました。 StackLayoutの幅と高さを可能な限り埋めたいが、実際の画像をトリミングする必要はありませんでした。ここでの回答は、正しい方法を見つけるのに役立ちました。ここに私のために働いたものがあります:

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

たぶんそれは誰かのために役立つでしょう。

明確化:

Horizo​​ntalOptionsおよびVerticalOptionsの値はFillAndExpandであるため、グリッドの高さと幅は親を埋めるように調整されます。この場合Stacklayoutです。画像はグリッドの子であるため、親に従って変換されます(画像に追加のオプションを指定していません)。

画像のアスペクトはAspectFitに設定されているため、画像はビュー(この場合はグリッド)に適合し、その比率も保持されます。

このように、画像がポートレートモードであるが狭すぎる場合、グリッド(StackLayout)の高さを埋めますが、その比率を維持し、上または下から切り取られないように幅を埋めません。

画像がランドスケープモードの場合、グリッド(StackLayout)の幅を埋めますが、その比率を維持し、左または右からトリミングされないようにするために、高さを埋めません。

7
Sonia

実例が見つからなかったので。これは私にとって完璧に機能します:

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

Aspect = "AspectFit"は、レイアウト内に画像を収めるために使用します。画像が小さい場合、スペースを残すことができます。 Aspect = "AspectFill"は、画像をレイアウト内に収めるために使用し、画像を伸ばしてスペースをフルにし、親レイアウトスペースに関して画像が小さいか、スペースを残しません。 AspectFitの代わりにAspectFillを使用する必要があります。

3
Naveen

FFImageLoading NuGetパッケージのCachedImageを使用してみてください

MyPage.xaml

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

これにより、コンテナを水平方向に塗りつぶし、アスペクトを維持しながら自動的に幅を生成しようとするイメージが生成されます。

このコード行をMainActivity.xamlglobal::Xamarin.Forms.Forms.Init(this, bundle);の後に追加します

_CachedImageRenderer.Init(true);
_

例があります here

2
Michael Yuwono

次のようなグリッド内に画像を含めてみてください。

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

適切にサイズ変更されていない画像がある場合、グリッド内に画像を含めると問題が解決することがあります。

1
Bjt1776

これには、両方のプラットフォームのカスタムレンダリングが必要です。 ImageRendererを継承するFillScreenImageRendererを作成します。

<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;
    }

アンドロイド:

    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

stacklayoutのheightrequestは、自動的に高さを調整するために、StartAndExpand、FillAndExpand、EndAndExpandのいずれかでなければなりません

0
Jay Patel