読者です 読者をやめる 読者になる 読者になる

高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

にじいろスコープがリリースされました

ガジェット プログラミング

Windows Phoneアプリケーショントライアスロン2種目目、にじいろスコープが公開されました。

今回のアプリはえらく単純。カメラ内の映像の色相を画面左上の色相環にプロットするだけのアプリです。ARのはしり と言えなくもないですが。
屋外でも何度か使ってみましたが、結構面白いです。こういう方向のアプリもまた作ってみたいかな。

開発後期

今回は、1種目目の声かけカメラに続くカメラアプリ。カメラアプリの全ピクセル値のスキャンには、MSDNにも掲載されていますが、PhotoCamera#GetPreviewBufferArgb32()メソッドを使用します。前回も書いたとおり、ここからの画面遷移がある場合は、PhotoCameraオブジェクトが予期しないタイミングでnullになっていることがあったりしますので注意。nullチェックは怠らないようにしましょう。


で、RGBで取得した値ををArray#ForEach()メソッドで全スキャンして、HSVに変換→Hの値を取得しています(今回HSVのうちSとVが0.2を下回る色(暗い色/無彩色に近い色)は無視しています)。

   Array.ForEach<int>(ARGBPx, delegate(int c)
   {
       int a = c >> 24;
       int r = (c & 0x00ff0000) >> 16;
       int g = (c & 0x0000ff00) >> 8;
       int b = (c & 0x000000ff);
       HsvColor hsv = HsvColor.FromRgb(Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b));
       if (hsv.V > 0.2 && hsv.S > 0.2)
       {
           hues[(int)hsv.H] += 1;
           brights[(int)hsv.H] += hsv.V;
       }
   });

HsvColorについては、RGBをHSV(HSB)、HSL(HLS)、HSIに変換、復元する: .NET Tips: C#, VB.NETに掲載されているクラスを多少加工して使用しました。

WriteableBitmapEx

今回は色相環の描画など大量の描画処理が入ります。これらは標準メソッドで描くことも出来ないことはないのですが、WriteableBitmapExを使うのが便利です。これを使えば、他の言語の描画系ライブラリで割とおなじみのDraw***、Fill***メソッドが利用出来るようになります。しかも全てのメソッドは拡張メソッドとして定義されているので、WriteableBitmapの使い勝手は全く変わらない。

  int center = circle.PixelWidth / 2;
  int radius = center - 2;
  int hrad = radius / 2;
  for (int i = 0; i < 360; i++)
  {
      Color color = HsvColor.ToRgb(new HsvColor(i, 1, 1));
      double rad = arc2rad(i);
      double rad2 = arc2rad(i + 2);
      circle.FillCurveClosed(new int[]{
          center, center, 
          rad2pointX(rad, radius, center), rad2pointY(rad, radius, center),
          rad2pointX(rad2, radius, center), rad2pointY(rad2, radius, center)}, 
          0.0f, color);
  }
 ・・・
  private double arc2rad(int i)
  {
     double rad = 0;
     if (i > 0) rad = i * Math.PI / 180;
     return rad;
  }
  private int rad2pointY(double rad, int radius, int center)
  {
      return (int)((float)Math.Sin(rad) * radius + center);
  }
  private int rad2pointX(double rad, int radius, int center)
  {
      return (int)((float)Math.Cos(rad) * radius + center);
  }

円の角度→座標への変換はサインやコサインの値を使用します。この辺多少でも数学をかじっていれば当たり前の数式なんじゃないかとは思いますが、今ひとつこれといった方法が思いつかず苦労しました。

今後の展開

このアプリとしては、バージョン情報画面が他の2アプリと違いやけに簡素なところからわかるかもしれませんが、この先はあまり考えてません。

色相を使ったネタは多分もっとファッション分野などに活用出来そうな気はするのですが、自分程度の色彩の知識ではこの辺が限界かな と。もうちょっと詳しい人ならトーンから合いそうな色を提案したりとか様々な機能を付与出来るかもしれないですが、そこまで出来るほどわたしには知識がなかった。
アプリケーションを作るにあたり、それぞれの分野の専門知識があるとたぶん面白くなるんだろうなー などと思った次第。

ひとまず、今後の状況によってはバージョンアップもすると思いますが、ひとまずこんなところで。さて、3種目全部公開されたので早くトライアスロンを完走させよう。