LemonteaのUnity部屋

C#とかのお話です~

Xamarin Bitmapを作成して保存する

こんにちは。レモンティーです。

今回は、Bitmapを作成して保存します。

ユーザーの描いた絵を保存したい時とかですね。
今回はAndroid.GraphicsのBitmapを使うので
もしFormsから使う場合はDependencyServiceで呼ぶことになります。
www.sawalemontea.com


さっそく作成と保存をやっていきます。
まず

using Android.Graphics;
using System.IO;

としておいて
Bitmapを作成

var bitmap = Bitmap.CreateBitmap(colors,width,height, Bitmap.Config.Argb8888);

Bitmapを保存

 using (var filestream = new FileStream(filepath,FileMode.Create))
 {
     bitmap.Compress(Bitmap.CompressFormat.Png, 100, filestream);
 }

でできます。

以下、作成時の引数を補足します。

Bitmap.CreateBitmap(colors,width,height,Bitmap.Config.Argb8888)

width height は作成されるBitmapの大きさです。

そしてそのwidth*height個のマスにセットされる
色のデータのint配列がcolorsです。

色のデータのint配列、と言いましたが
色をどのようにintで表現するのでしょうか。
それを指定するのがBitmap.Configです。

たとえばArgb8888では、あるマスの色を
アルファ値、赤、緑、青
の4つの要素で表現し、
それぞれが8ビット…つまり0~255の256段階で表されます。

各要素は16進数二桁なので、
これをARGBの順に並べて10進数に直せば
colorsのそのマスの分のintが求まります。
例えば 
ff8b33ca は 4287312842 です…
…が、変な手間がかかってるので
もっといいやりかたがあるかもしれません。

一応、この考え方の場合の
colors用の色のintデータの求め方を以下に書いておきますが、
ちゃんとしたい場合は調べてみてください…

private int GetIntColor(byte a,byte r,byte g,byte b)
        {
            var a2 = a % 16;
            var a1 = (a - a2) / 16;
            var r2 = r % 16;
            var r1 = (r - r2) / 16;
            var g2 = g % 16;
            var g1 = (g - g2) / 16;
            var result = 268435456 * a1 + 16777216 * a2 +
                1048576 * r1 + 65536 * r2 +
                4096 * g1 + 256 * g2 +
                b;
            return result;
        }

268435456とかは16の○乗です。
ちなみに、Xamarin.FormsのColorから変換する場合は
A,R,G,Bプロパティをそれぞれ255倍してから同様に変換すればできます。

なので例えば以下のようにすると
グラデーションのBitmapが作成and保存できます。

            var width = 128;
            var height = 128;
            var colors = new List<int>();            

            for (int h = 0; h < height; h++)
            {
                for (int w = 0; w < width; w++)
                {
                    colors.Add(GetIntColor(255,(byte)(h%256),(byte)(w%256),0));
                }
            }

           var bitmap = Bitmap.CreateBitmap(colors.ToArray(),width,height, Bitmap.Config.Argb8888);

           using (var filestream = new FileStream(filepath,FileMode.Create))
           {
                bitmap.Compress(Bitmap.CompressFormat.Png, 100, filestream);
           }

f:id:sawalemontea:20180423182937p:plain

たしかに青はずっと0、アルファはずっと255で
右ほど緑が強く、下ほど赤が強くでていますね。

今回はこれでおしまいです。
www.sawalemontea.com

www.sawalemontea.com

C# 文字列とバイト配列の変換 Text.Encoding GetBytesとGetString

こんにちは。レモンティーです。

文字列を数字のデータにして扱いたい時ってありますよね?
そこで今回は、文字列とバイト配列の相互変換です。

文字列→バイト配列

var data = Encoding.UTF8.GetBytes(text);

バイト配列→文字列

var text = Encoding.UTF8.GetString(data);

どちらも

using System.Text

がいります。

また、UTF8の部分は文字コードなので
GetBytesとGetStringで同じものを使えばOKです。
それぞれの解説はここ↓とかにあります。
www.graffe.jp


今回はこれでおしまいです。
www.sawalemontea.com

Xamarin.Forms 待機中にぐるぐるを表示させる ProgressDialog

こんにちは。レモンティーです。

今回は、Xamarinで待ち時間にぐるぐる回るやつを表示させます。

普通Xamarin.Formsでぐるぐると言ったらActivityIndicatorですが
今回はネイティブのものをDependencyServiceで呼びます。
www.sawalemontea.com

さっそくやっていきます。

インターフェース内

共通のインターフェースにはこんな感じで書きます。
using System.Threading.Tasks; が必要です。

Task<T> WaitTask<T>(Task<T> task);

固有実装

そうしたらプラットフォームごとに実装していきます。

Android

AndroidではProgressDialogを使います。

  public async Task<T> WaitTask<T>(Task<T> task)
        {
           //ぐるぐる作成
            var prg = new ProgressDialog(Forms.Context);
            prg.SetTitle("処理中…");
            prg.SetMessage("現在処理中です。");
            prg.SetCancelable(false);
            prg.SetProgressStyle(ProgressDialogStyle.Spinner);
            //ぐるぐる表示
            prg.Show();
            //時間のかかる処理
            var result = await task;
            //ぐるぐるを閉じる
            prg.Dismiss();
            return result;
        }

使用

使うときはこのように呼び出します。

var result = await Dependencyservice.Get<ITest>.WaitTask<string>(Task.Run(async () => await GetTextAsync()));

GetTextAsynkの部分にぐるぐるを表示して待ちたい非同期メソッドを入れます。
その返り値に合わせて<string>の部分を変えます…が、これは省略可能です。

返り値が無い場合は、
インターフェースから全部<T>が無いバージョンを使えばOKです。


これで時間がかかる処理の間、画面が固まるのを避けつつ、
操作は待ってもらうことができます。
じゃないと使ってるときに急に固まったら
バグったみたいに見えちゃいますからね。

今回はこれでおしまいです。
www.sawalemontea.com

Xamarin 埋め込みリソースを読み込む

こんにちは。レモンティーです。

今回は埋め込みリソースの読み込みです。

テキスト形式のデータを、ソースに直接書かずに
使いたい場合がありますよね。
そんな時に役立ちます。

埋め込みリソースを作る

適当な場所で
追加→新しい項目→テキストファイル
をして新しいテキストファイルをつくります。
(外で作ったファイルを貼り付けてもOKです)
f:id:sawalemontea:20180413215740p:plain

追加したファイルのプロパティから
ビルドアクションを埋め込みリソースに変更します。
f:id:sawalemontea:20180413215840p:plain

読み込む

読み込むには↓のようにします

using System.IO;
using System.Reflection;

________________________

        public string GetResourceText(string path)
        {
            var text = "";
            var assembly = typeof(このメソッドを持つクラス).GetTypeInfo().Assembly;
            Stream stream = assembly.GetManifestResourceStream(path);
            using(var reader = new StreamReader(stream))
            {
                text = reader.ReadToEnd();
            }

            return text;
        }

pathはこの場合
TestApp.TestFolder.TextFile1.txt
となります。


今回はこれでおしまいです。

www.sawalemontea.com