none
XamarinでPictureBoxの様なコントロールはあるのでしょうか? RRS feed

  • 質問

  • Xamarinで通常のC#の様に、『DrawImage』、『DrawString』は出来ないのでしょうか?

    出来ない場合、どの様な方法で行えばよいのでしょうか?

    2020年2月3日 9:10

回答

  • Xamarin初心者さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    これは、ペイントイベントで最後のhelloBitmapのみを描画したためです。
    次のようなビットマップを保存してみてください。
    List<SKBitmap> bitmaps = new List<SKBitmap>();
    private async void Pic()
    {
                
        for (int i = 1; i <= 10; i++)
        {
            string url = "";
    
            url = "https://c.tile.openstreetmap.org/" + 18 + "/" + (233891 + i) + "/" + 100481 + ".png";
    
    
            try
            {
                var httpClient = new HttpClient();
                using (Stream stream = await httpClient.GetStreamAsync(url))
                using (MemoryStream memStream = new MemoryStream())
                {
                    await stream.CopyToAsync(memStream);
                    memStream.Seek(0, SeekOrigin.Begin);
                    //helloBitmap = SKBitmap.Decode(memStream);
                    bitmaps.Add(SKBitmap.Decode(memStream));
                }
            }
            catch(Exception e)
            {
            }
        }
    
        SKCanvasView canvasView = new SKCanvasView { WidthRequest = 1000 };
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = new ScrollView { Content = canvasView, Orientation = ScrollOrientation.Horizontal };
    }
    
    

    ここにスクロールビューを追加して、画像のサイズが画面より大きい場合にコンテンツをスクロールできるようにしました。
    ペイントイベントも変更しました。
    private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
    
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;
    
        using (surface = SKSurface.Create(new SKImageInfo(1000, 1000)))
        {
            for (int i = 0; i < bitmaps.Count; i++)
            {
                canvas.DrawBitmap(bitmaps[i], 256 * i, 0, null);
            }
        }
    }

    using (surface = SKSurface.Create (width: 1000, height: 1000, SKImageInfo.PlatformColorType, SKAlphaType.Premul)は推奨されないため、代わりにコンストラクターを使用してください。

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年2月12日 7:12
    モデレータ

すべての返信

  • Xamarin.Forms でグラフィックにあるCocosSharp/SkiaSharp/UrhoSharpのようなライブラリのコントロールを使います。
    それぞれのページにサンプルコードがあるので試してみるといいです。

    たとえばSkiaSharpだとSKCanvasにDrawBitmapやDrawTextといった描画ができます。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年2月3日 15:01
  • ご回答ありがとうございます。

    サンプル(SkaiSharp)を使用して、画像を表示できたのですが、

    複数枚のビットマップを同時に表示する処理が分かりません。

    ※タイル表示の様な感じで表示したいと思っています。

    2020年2月4日 7:12
  • 「タイル表示の様な」であれば「SkiaSharp のビットマップのタイル」にサンプルがあります。

    同じビットマップを繰り返しではなく、異なる種類のビットマップを同時に表示したいという意味であれば、

    方法1:SKCanvasに対して描画する領域をずらしながら描画する。

    DrawBitmapメソッドには4引数のものがあるので、sourceとdestを指定することでSKCanvasのdest領域に描画できます。
    このdestを縦横にずらして別のビットマップを描画すれば、1つのSKCanvasに複数のビットマップを描画できることになる。

    方法2:SKCanvasViewを複数配置する

    ページのXamlにGridなどを用意して、それぞれの升にSKCanvasViewを配置する。
    そのそれぞれのSKCanvasViewのPaintSurfaceイベントを処理することで複数のビットマップを描画できることになる。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年2月4日 9:03
  • ご回答誠にありがとうございます。

    色々と試している途中なのですが…

    Pic()で適当なオープンストリートマップを取得して、表示するものです。

    現状、1枚の画像しか表示されません。

    [Obsolete]
    private async void  Pic()
    {
    
    	for (int i = 1; i <= 10; i++)
    	{
    	    string url = "";
    
    	    url = "http://c.tile.openstreetmap.org/" + 18 + "/" + (233891 + i) + "/" + 100481 + ".png"
    
    	    try
    	    {
    	        using (Stream stream = await httpClient.GetStreamAsync(url))
    	        using (MemoryStream memStream = new MemoryStream())
    	        {
    	            await stream.CopyToAsync(memStream);
    	            memStream.Seek(0, SeekOrigin.Begin);
    	            helloBitmap = SKBitmap.Decode(memStream);
    	        }
    
    	        using (SKCanvas bitmapCanvas = new SKCanvas(helloBitmap))
    	        {
    	            bitmapCanvas.DrawBitmap(helloBitmap,i * 256,0,null);
    	        }
    	    }
    	    catch
    	    {
    	    }
    	}
    
    	SKCanvasView canvasView = new SKCanvasView();
    	canvasView.PaintSurface += OnCanvasViewPaintSurface;
    	Content = canvasView;
    
    }
    
    [Obsolete]
    private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
    
    	SKImageInfo info = args.Info;
    	SKSurface surface = args.Surface;
    	SKCanvas canvas = surface.Canvas;
    
    	using (surface = SKSurface.Create(width: 1000, height: 1000, SKImageInfo.PlatformColorType, SKAlphaType.Premul))
    	{
    	    canvas.DrawBitmap(helloBitmap, 256, 256, null);
    
    	}           
    }


    2020年2月4日 10:10
  • Xamarin初心者さん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    これは、ペイントイベントで最後のhelloBitmapのみを描画したためです。
    次のようなビットマップを保存してみてください。
    List<SKBitmap> bitmaps = new List<SKBitmap>();
    private async void Pic()
    {
                
        for (int i = 1; i <= 10; i++)
        {
            string url = "";
    
            url = "https://c.tile.openstreetmap.org/" + 18 + "/" + (233891 + i) + "/" + 100481 + ".png";
    
    
            try
            {
                var httpClient = new HttpClient();
                using (Stream stream = await httpClient.GetStreamAsync(url))
                using (MemoryStream memStream = new MemoryStream())
                {
                    await stream.CopyToAsync(memStream);
                    memStream.Seek(0, SeekOrigin.Begin);
                    //helloBitmap = SKBitmap.Decode(memStream);
                    bitmaps.Add(SKBitmap.Decode(memStream));
                }
            }
            catch(Exception e)
            {
            }
        }
    
        SKCanvasView canvasView = new SKCanvasView { WidthRequest = 1000 };
        canvasView.PaintSurface += OnCanvasViewPaintSurface;
        Content = new ScrollView { Content = canvasView, Orientation = ScrollOrientation.Horizontal };
    }
    
    

    ここにスクロールビューを追加して、画像のサイズが画面より大きい場合にコンテンツをスクロールできるようにしました。
    ペイントイベントも変更しました。
    private void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
    
        SKImageInfo info = args.Info;
        SKSurface surface = args.Surface;
        SKCanvas canvas = surface.Canvas;
    
        using (surface = SKSurface.Create(new SKImageInfo(1000, 1000)))
        {
            for (int i = 0; i < bitmaps.Count; i++)
            {
                canvas.DrawBitmap(bitmaps[i], 256 * i, 0, null);
            }
        }
    }

    using (surface = SKSurface.Create (width: 1000, height: 1000, SKImageInfo.PlatformColorType, SKAlphaType.Premul)は推奨されないため、代わりにコンストラクターを使用してください。

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Haruka
    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年2月12日 7:12
    モデレータ