2008年5月31日土曜日

[他]SQLServer2005Expresss用ツール

SQLServer2005Expressにはツールが何もついていません。そのため手動でツールを入れる必要があります。そのうちの1つはMicrosoft SQL Server Management Studio Expressです。こちらはMSのサイトということもあり、比較的探しやすいと思います。しかし、プロファイラはMSからは提供されていません。

半ばあきらめていたんですが、SQL Server 2005 Express Profilerというそのままの名前のツールが紹介されていました。これを忘れないようにメモっておこう。

2008年5月28日水曜日

[他]Web開発用のプロキシツール Fiddle

Web系のシステムを開発していると、ブラウザに表示されているHTML以外の情報(HTTPヘッタなど)を見たいときがあります。そんな時Fiddleという超便利なツールがあります。

このツールを起動すると、IEのプロキシ情報を勝手に更新し、横取りするようになります。結果、通信している情報をトレースすることができます。あ、動作させるためには、.NET Framework1.1以降が必要です。

しかし、私の環境では、特定のJavaScriptでエラーが発生します。私の環境だけかも知れませんが。。。

2008年5月21日水曜日

[.NET]年齢の計算

年齢を計算するのは、単純なようで意外とおくが深いのです。.NETの場合、単純な計算であれば、DateTime.Subtractにて算出可能です。コードはこんな感じ。

DateTime dt1 = dateTimePicker1.Value; //基準日
DateTime dt2 = dateTimePicker2.Value; //誕生日
TimeSpan sp = dt1.Subtract(dt2);int age = new DateTime(sp.Ticks).Year -1;


この計算を実施した場合、2/29生まれの人は以下のようになります。
  • うるう年以外の場合、2/28日が誕生日(誕生日が1日前倒し?)
  • うるう年は2/29日が誕生日

ほかの方法がないかと調査してみたところ、年齢を算出する計算式があることがわかりました。なんでも (本日-誕生日)/10000 の小数点以下切捨てで計算できるようです。コードはこんな感じ。

DateTime dt1 = dateTimePicker1.Value; //基準日
DateTime dt2 = dateTimePicker2.Value; //誕生日
long d1 = Convert.ToInt64(dt1.ToString("yyyyMMdd")); //基準日を数値に変換
long d2 = Convert.ToInt64(dt2.ToString("yyyyMMdd")); //誕生日を数値に変換
int age = (int)Math.Floor((double)((d1-d2)/10000));


理屈的に満年齢と考えたとき、うるう年が誕生日の人はうるう年ではない年は3/1が誕生日のような気がします。なんといっても「満」年齢ですからねぇ。
どちらの方式も基本的に誕生日当日の0時0分0秒を持って+1歳する方式なんですが、うるう年が誕生日の人をどのようにするかにより、計算式を切り替えればよい。ということになりますね。

2008年5月18日日曜日

[.NET]画像処理グレースケール化(3)

[.NET]画像処理グレースケール化(1)(2)では、画像を1pixelずつ操作し、その平均値をセットしなおすという方法をとってきましたが、今度は、.NET Frameworkに存在するColorMatrixというクラスを使用してグレースケール化します。

コード例はこんな感じ。

//RGBATのそれぞれの値をどのように変化させるかを配列に保持(RGB値を1/3にする)
float[][] gm = new float[][]{
    new float[]{1/3f,1/3f,1/3f,0.0f,0.0f},  // R 
    new float[]{1/3f,1/3f,1/3f,0.0f,0.0f},  // G
    new float[]{1/3f,1/3f,1/3f,0.0f,0.0f},  // B
    new float[]{0.0f,0.0f,0.0f,1.0f,0.0f},  // A
    new float[]{0.0f,0.0f,0.0f,0.0f,1.0f}}; // Three Translations

Bitmap bmp = new Bitmap(ctlPicture.Image);
ColorMatrix gcm = new ColorMatrix(gm);
using (ImageAttributes gia = new ImageAttributes())
using (Graphics g = Graphics.FromImage(bmp))
{
    gia.SetColorMatrix(gcmColorMatrixFlag.DefaultColorAdjustType.Bitmap);
    g.DrawImage(bmpnew Rectangle(00bmp.Widthbmp.Height), 00bmp.Widthbmp.HeightGraphicsUnit.Pixelgia);
    ctlPicture.Image = bmp;
}


この方式は、RGBAいずれかの要素のみを変換するということにいては汎用的であり、意外とよい方法といえそうです。

ちなみにこの方式では、約50ms程度で処理が終わります。一番遅い方式と比べると約14倍のパフォーマンスが出ています。
また、この3つの方式で生成される画像をファイルにbitmap形式で保存しても、同じデータにはなりませんでした。結果から、この方式は四捨五入していることがわかりました。ということで条件を合わせるために、他の方式も四捨五入しています。

[.NET]画像処理グレースケール化(2)

GDD Blog: [.NET]画像処理グレースケール化(1)」で約700msかかっていた処理ですが、P/InvokeやUnsafeを使わなくてもLockBitsを使いBitmapの内部データにアクセスすることにより、高速化が可能です。
処理の内容としては以下のとおり。
  • LockBitsを使い、bitmapの内部データをシステム メモリにロックします
  • そのデータを、Byte[]にコピーします
  • 3byteずつを1pixelのカラーデータとし、その平均をセットしなおします(これは[.NET]画像処理グレースケール化(1)と同じ処理)

コードはこんな感じ。



Bitmap bmp = new Bitmap(ctlPicture.Image);

//bitmapをメモリ上にロックします
Rectangle rect = new Rectangle(00bmp.Widthbmp.Height);
BitmapData bmpData = bmp.LockBits(rectImageLockMode.ReadWrite,
                                          PixelFormat.Format24bppRgb);

// RGB値をbyte列にコピーする
IntPtr ptr = bmpData.Scan0;
int stride = bmpData.Stride;
int size = stride * bmp.Height;
byte[] rgbValues = new byte[size];

System.Runtime.InteropServices.Marshal.Copy(ptrrgbValues0size);

//3byteずつ進む
for (int j = 0j < sizej = j + 3)
{
    byte val = (byte)Math.Round((double)(rgbValues[j + 0] + rgbValues[j + 1] + rgbValues[j + 2]) / 3);
    rgbValues[j] = val;     //b
    rgbValues[j + 1] = val//g
    rgbValues[j + 2] = val//r
}

// byte列をbitmapに復元し、メモリのロックを開放する
System.Runtime.InteropServices.Marshal.Copy(rgbValues0ptrsize);
bmp.UnlockBits(bmpData);

ctlPicture.Image = bmp;


このコードにより、同じ環境でも処理速度が30ms程度になります。パフォーマンスが約23倍になりました。

[.NET]画像処理グレースケール化(1)

.NET Frameworkを使用したWindowsアプリケーションでは、簡単に画像を画面に表示することができます。
簡単に言うと、画像をBitmapに読み込み、PictureBoxのImageプロパティに設定するだけです。

しかし、その画像をなんらか加工するためには、自力で処理する必要があります。たとえは画像をグレースケール化するためには、RGBの値の平均値をRGBそれぞれにセットするという式処理することができます。
コードの例は、こんな感じ。

Bitmap bmp = new Bitmap(ctlPicture.Image);
for (int i = 0i < bmp.Widthi++)
{
    for (int j = 0j < bmp.Heightj++)
    {
        Color color = bmp.GetPixel(ij);
        // 計算式にて、値を算出してセットする
        //int col = (int)((color.R + color.G + color.B) / 3);
        int col = (int)Math.Round((double)(color.R + color.G + color.B) / 3);
        bmp.SetPixel(ijColor.FromArgb(colcolcol));
    }
}
ctlPicture.Image = bmp;


しかしGetPixelとSetPixelを使ったやり方は、パフォーマンスが出ません。
ちなみに、
  • CPU:C2D 2.0GHz
  • メモリ:2GB
  • 対象の画像:645×425 24bitカラー

という環境で動作させると、この方法では約700ms程度の時間がかかります(リリースコンパイルで実行)。
次回、これを高速化する方法を紹介します。

2008年5月4日日曜日

[.NET]変数のサフィックス

変数に値を設定する時、ほとんどの場合暗黙の型変換によりセットされますが、明示的に型を指定することができます。主な型だけですが、型指定する場合、以下のようになります。
しかし、なぜバイト型にはサフィックスがないんですかねぇ?

.NET定義C#VB.NET
サフィックスサフィックス
System.Bytebyteなし -  
System.Charcharなし'a'CharC"a"C
System.Int16-  ShortS1000S
System.Int32intなし IntegerI1000I
System.Int64longL/l1000LLongL/&1000L
System.Decimaldecimalm/M1000MDecimalD/@1000D
System.Singlefloatf/F10.0FSingleF/!10.0F
System.Doubledoubled/D10.0DDoubleR/#10.0R

2008年5月3日土曜日

[.NET]三項演算子のなぞ

C#には、暗黙の型変換で数値型の変数にキャストすることなく値をセットすることもできます。
また、明示的に数値に型を持たせることができます。例を書くとこんな感じ。

byte b = 100;
int i = 100;
int ii = 100L;// 明示的に型指定するのでコンパイルエラー
long l = 100;
double d = 100;

また、3項演算子という構文があります。これはif文と代入を組み合わせたような構文になります。

int foo = 0;
foo = foo == 0 ? 100 : 0//コンパイルOK

byte bar = 0;
bar = bar == 0 ? 100 : 0//コンパイルNG

long hoge = 0;
hoge = hoge == 0 ? 100 : 0//コンパイルOK


暗黙の型変換で、barもコンパイルが通るような気がします。気になったので、イミディエイトで以下を実行してみました。

(foo == 0 ? 100 : 0).GetType()


すると、型はSystem.Int32でした。

ということで値の桁落しないlongはそのまま値が設定可能で、オーバーフローするbyte型はキャストしないと問題が発生する可能性があるということで、コンパイラーが教えてくれるってことなんでしょう。。。

2008年5月2日金曜日

[他]失敗しない「システム移行」

最近、@it の最強チームで挑んだ、「40時間でデータ移行」の壁 を読みました。
データ移行では、移行プログラムの準備もさることながら、リハーサルや日程など、いかに準備をするか。というがまとめられております。ノンフィクションだと思われるその記事は、ものすごく臨場感があり、一気に最後まで読んでしまいました。


依然私が携わっていたシステムでも、これほど大きな移行はありませんでしたが、どのデータをどのように変更するといったことを記載した、移行計画書を準備し、テスト環境を作り、データ移行のシミュレーションをやったことを思い出しました。

そのときは、確認試験が1点もれており、そのもれた点が後に障害として発覚するという、なんとも情けない経験をしたことがあります。この記事を読んで、そのときのことを思い出しました。


そしてもうひとつ。ItProに最後の難関 システム移行という記事があります。ここではシステム移行に関するノウハウが集約されているようです。移行がある場合、参考になると思います。

私も、このサイトを読んでもう一度基本に立ち戻ろうと思います。