Xamarinで、画像を作成する
投稿者 魔界の仮面弁士  (社会人)
投稿日時
2024/3/6 17:58:22
提示されたサンプルコードは、Pen の Dispose が漏れてます…。
(そもそも、C# 初級講座の記事が、using 無しのコードになっているわけですが)
System.Drawing は GDI+ (一部 GDI) 依存のライブラリなので、
Windows 以外のプラットフォームには向きません。
一応、mono の sysdrawing-coregraphics な実装はあるのですけれどね。
https://learn.microsoft.com/ja-jp/xamarin/cross-platform/internals/available-assemblies
Shape や Path で表現するか、Canvas 、Paint あたりについて調べてみてください。
Xamarin の場合
https://learn.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/shapes/?WT.mc_id=DT-MVP-8907
https://learn.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/graphics/skiasharp/?WT.mc_id=DT-MVP-8907
https://dev.classmethod.jp/articles/xamarin-android-draw-line/
.NET MAUI の場合
https://learn.microsoft.com/ja-jp/dotnet/maui/user-interface/graphics/draw?WT.mc_id=DT-MVP-8907&view=net-maui-8.0
> c#の初級講座で、
誤)c#
正)C#
(そもそも、C# 初級講座の記事が、using 無しのコードになっているわけですが)
System.Drawing は GDI+ (一部 GDI) 依存のライブラリなので、
Windows 以外のプラットフォームには向きません。
一応、mono の sysdrawing-coregraphics な実装はあるのですけれどね。
https://learn.microsoft.com/ja-jp/xamarin/cross-platform/internals/available-assemblies
Shape や Path で表現するか、Canvas 、Paint あたりについて調べてみてください。
Xamarin の場合
https://learn.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/shapes/?WT.mc_id=DT-MVP-8907
https://learn.microsoft.com/ja-jp/xamarin/xamarin-forms/user-interface/graphics/skiasharp/?WT.mc_id=DT-MVP-8907
https://dev.classmethod.jp/articles/xamarin-android-draw-line/
.NET MAUI の場合
https://learn.microsoft.com/ja-jp/dotnet/maui/user-interface/graphics/draw?WT.mc_id=DT-MVP-8907&view=net-maui-8.0
> c#の初級講座で、
誤)c#
正)C#
投稿者 kojiro  (社会人)
投稿日時
2024/3/7 23:28:59
SkiaSharpを研究してみましたが、実際の稼働には及ばずです。
Xamarinでは、あきらめて、JavaScriptを検討してみます。
ありがとうございました。
Xamarinでは、あきらめて、JavaScriptを検討してみます。
ありがとうございました。
投稿者 kojiro  (社会人)
投稿日時
2024/3/13 16:37:51
.NET MAUIによるマルチプラットフォームアプリ開発 がVisual Studioで、できるようですね。
以下参考です。
https://learn.microsoft.com/ja-jp/dotnet/maui/get-started/first-app?view=net-maui-8.0&tabs=vswin&pivots=devices-android
https://www.amazon.co.jp/gp/product/4296080237/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
以下参考です。
https://learn.microsoft.com/ja-jp/dotnet/maui/get-started/first-app?view=net-maui-8.0&tabs=vswin&pivots=devices-android
https://www.amazon.co.jp/gp/product/4296080237/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
投稿者 kojiro  (社会人)
投稿日時
2024/4/21 16:43:52
.NET MAUIを使って、WindowsのPictureBoxのような役目を持たすことに、成功しました。GraphicsViewコントロールを使うようで、描画だけしかできないと、思っていましたが、https://github.com/dotnet/Microsoft.Maui.Graphics/discussions/332により、コントロール内の座標を得ることにも成功しました。
投稿者 kojiro  (社会人)
投稿日時
2024/4/21 19:58:38
参考までに、実現までのプロセスを書きます。
.NET MAUIは、.NETマルチプラットフォーム・・、ASP.NETとWeb開発、.NETデスクトップ開発にチェックを入れて、VS2022Communityをインストールしました。新しいプロジェクトで、.NET MAUI アプリを選んで、作ります。画像にあるのは、MainPage.xamlとMain.Page.XAml.csです。プロジェクト名は、MAUITOUCHとしております。エミュレーターは、ASP29あたりで作るとよいと思います。BIOSのVirtualizationにチェック(これは、ほぼ、入っていると思います)。それから、"Hyper-V"機能を有効にしないと、エミュレーターは、なかなか動かないと思います。実機への装着などは、Android Studioなどと同じです。VS2022でエラーが出た場合、色々VSのソフトやネットで調べましたが、ChatGPT(https://chat.openai.com/)が参考になることを、話してくれることも、あります。間違ってても、勉強になりました。
.NET MAUIは、.NETマルチプラットフォーム・・、ASP.NETとWeb開発、.NETデスクトップ開発にチェックを入れて、VS2022Communityをインストールしました。新しいプロジェクトで、.NET MAUI アプリを選んで、作ります。画像にあるのは、MainPage.xamlとMain.Page.XAml.csです。プロジェクト名は、MAUITOUCHとしております。エミュレーターは、ASP29あたりで作るとよいと思います。BIOSのVirtualizationにチェック(これは、ほぼ、入っていると思います)。それから、"Hyper-V"機能を有効にしないと、エミュレーターは、なかなか動かないと思います。実機への装着などは、Android Studioなどと同じです。VS2022でエラーが出た場合、色々VSのソフトやネットで調べましたが、ChatGPT(https://chat.openai.com/)が参考になることを、話してくれることも、あります。間違ってても、勉強になりました。
投稿者 kojiro  (社会人)
投稿日時
2024/4/23 16:55:00
示したコードは、確かにマウスクリック時の座標を、Textという名前のラベルに示しますが、マウスクリック時の座標を中心とした円を作成することは、できていません。どなたか、教えていただければ、幸いです。_(\\)_
投稿者 kojiro  (社会人)
投稿日時
2024/4/23 17:40:50
適当な時に、トライしたことも含めて、新しくスレッドを立てます。
投稿者 kojiro  (社会人)
投稿日時
2024/4/23 21:02:09
MauiTouch1として作ったプログラムを、公開しておきます。画像は少し違います。
MainPage.xaml:
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTouch1"
x:Class="MauiTouch1.MainPage">
<ContentPage.Resources>
<local:GraphicsDrawable x:Key="drawable" />
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label
Text="グラフィック描画"
x:Name="Text"
FontSize="18"
HorizontalOptions="Center" />
<GraphicsView
Drawable="{StaticResource drawable}"
x:Name="graph"
HeightRequest="200" WidthRequest="200"
StartInteraction="OnStartInteraction"
EndInteraction="OnEndInteraction"
/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs
です。MainPage.xamlで残っている最初の行
<?xml version="1.0" encoding="utf-8" ?>
は取らないと、エラーになります。
MainPage.xaml:
ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTouch1"
x:Class="MauiTouch1.MainPage">
<ContentPage.Resources>
<local:GraphicsDrawable x:Key="drawable" />
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label
Text="グラフィック描画"
x:Name="Text"
FontSize="18"
HorizontalOptions="Center" />
<GraphicsView
Drawable="{StaticResource drawable}"
x:Name="graph"
HeightRequest="200" WidthRequest="200"
StartInteraction="OnStartInteraction"
EndInteraction="OnEndInteraction"
/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs
namespace MauiTouch1;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void OnStartInteraction(object Sender, TouchEventArgs evt)
{
PointF firstPoint = evt.Touches.FirstOrDefault();
string msg = $"Touch/click at {firstPoint}";
Text.Text = msg;
}
private void OnEndInteraction(object Sender, TouchEventArgs evt)
{
PointF lastPoint = evt.Touches.LastOrDefault();
string msg = $", released at {lastPoint}";
Text.Text += msg;
}
}
public class GraphicsDrawable : IDrawable
{
public void Draw(ICanvas canvas, RectF dirtyRect)
{
canvas.FillColor = Colors.DarkBlue;
canvas.FillCircle(100, 100, 80);
canvas.StrokeColor = Colors.LightPink;
canvas.StrokeSize = 1;
double rad = 0;
float x1 = 200;
float y1 = 100;
for (int i = 0; i < 100; i++)
{
float x2 = (float)(Math.Cos(rad) * 100) + 100;
float y2 = (float)(Math.Sin(rad) * 100) + 100;
canvas.DrawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
rad += Math.PI * (170.0 / 180.0);
}
}
}
です。MainPage.xamlで残っている最初の行
<?xml version="1.0" encoding="utf-8" ?>
は取らないと、エラーになります。
投稿者 kojiro  (社会人)
投稿日時
2024/4/30 19:04:01
マイクロソフトコミュニティで、ついに解答を得ました。.NET MAUIのgraphicsVew コントロールで、そのコントロール内をタッチしたときに、それを中心とした円を描かせるコードを示してくださいました。
https://learn.microsoft.com/en-us/answers/questions/1660779/how-to-add-to-graphicsview-class-with-drawableprop
とりあえず、うれしいです。
https://learn.microsoft.com/en-us/answers/questions/1660779/how-to-add-to-graphicsview-class-with-drawableprop
とりあえず、うれしいです。
投稿者 kojiro  (社会人)
投稿日時
2024/5/8 16:57:20
最終的な、サンプルコードです。GraphicsViewコントロール内をクリックすると、円が描かれます。
MainPage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTouch2"
x:Class="MauiTouch2.MainPage">
<ContentPage.Resources>
<local:GraphicsDrawable x:Key="drawable" />
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<GraphicsView x:Name="graph" HorizontalOptions="Center" VerticalOptions="Start" HeightRequest="300" WidthRequest="300"
StartInteraction="OnStartInteraction" >
<GraphicsView.Drawable>
<local:GraphicsDrawable x:Name="drawable" />
</GraphicsView.Drawable>
</GraphicsView>
<Label
Text="text"
x:Name="Text"
FontSize="10"
HorizontalOptions="Start"
VerticalOptions="End"
/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs:
MainPage.xaml:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTouch2"
x:Class="MauiTouch2.MainPage">
<ContentPage.Resources>
<local:GraphicsDrawable x:Key="drawable" />
</ContentPage.Resources>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<GraphicsView x:Name="graph" HorizontalOptions="Center" VerticalOptions="Start" HeightRequest="300" WidthRequest="300"
StartInteraction="OnStartInteraction" >
<GraphicsView.Drawable>
<local:GraphicsDrawable x:Name="drawable" />
</GraphicsView.Drawable>
</GraphicsView>
<Label
Text="text"
x:Name="Text"
FontSize="10"
HorizontalOptions="Start"
VerticalOptions="End"
/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
MainPage.xaml.cs:
namespace MauiTouch2;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void OnStartInteraction(object sender, TouchEventArgs evt)
{
PointF firstPoint = evt.Touches.FirstOrDefault();
string msg = $"Touch/click at {firstPoint}";
Text.Text = msg;
await this.drawable.OnTouchAsync(this.graph, firstPoint, CancellationToken.None);
}
}
public class HitItem
{
public PointF pos { get; set; }
//public float radius { get; set; }
}
public class GraphicsDrawable : IDrawable
{
public List<HitItem> HitItems { get; } = new List<HitItem>();
public async Task OnTouchAsync(IGraphicsView view, PointF point, CancellationToken token)
{
HitItem c = new HitItem();
c.pos = point;
//c.radius = 0;
//lock (this.HitItems)
//{
this.HitItems.Add(c);
// }
// DateTime start = DateTime.Now;
// DateTime end = start.AddDays(1);
// while ( !token.IsCancellationRequested) //DateTime.Now <= end &&
// {
//c.radius = 20; // (float)(start - DateTime.Now).TotalSeconds * 100;
view.Invalidate();
await Task.Delay(30);
// }
//lock (this.HitItems)
//{
this.HitItems.Remove(c);
//}
//view.Invalidate();
}
public void Draw(ICanvas canvas, RectF dirtyRect)
{
DrawBack(canvas, dirtyRect);
DrawHitPoint(canvas, dirtyRect);
}
private void DrawHitPoint(ICanvas canvas, RectF dirtyRect)
{
if (HitItems.Count == 0)
{
return;
}
canvas.SaveState();
canvas.StrokeColor = Colors.Black;
canvas.StrokeSize = 2;
canvas.ClipRectangle(dirtyRect);
HitItem[] items;
lock (this.HitItems)
{
items = this.HitItems.ToArray();
}
// foreach (var item in items)
// {
canvas.DrawCircle(items[0].pos, 20);
// }
canvas.ResetState();
}
private void DrawBack(ICanvas canvas, RectF dirtyRect)
{
int x = 300;
canvas.StrokeColor = Colors.Black;
canvas.StrokeSize = 3;
canvas.DrawLine(0, 0, x, 0);
canvas.DrawLine(0, x, x, x);
canvas.DrawLine(0, 0, 0, x);
canvas.DrawLine(x, 0, x, x);
}
}
c#の初級講座で、
が、ありますが、xamarinでは、どんなコントロールを使って、作るのでしょうか?