C#プログラム画像処理

【C#】Rectangle<-->RectangleFの相互変換

あまりやる事は無いのですが、Rectangle(名前空間:System.Drawing)とRectangleFの相互変換について調べてみました。

RectangleからRectangleFへ変換

これに関しては、型は変わるものの、値そのものは変わらないので、ほぼ、代入するようなノリで以下のようにすると変換ができます。

var rect = new Rectangle(20, 10, 60, 40);
RectangleF rectF = rect;

RectangleFからRectangleへ変換

こちらは値を小数から整数へ切り詰める必要があるので、値を切り捨てや四捨五入する必要が出てきますがRectangle構造体には値を切り捨てる(intでキャストする)Truncateメソッド、切り上げを行うCeilingメソッド、四捨五入を行うRoundメソッドが用意されています。

ここでいうですが、RectangleF構造体のX, Y, Width, Heightプロパティに関して切り捨て、切り上げ、四捨五入が行われます。

 

プログラム例

var rectF = new RectangleF(0.5f, -1.5f, 10.5f, 5.5f);

Rectangle rect;
rect = Rectangle.Round(rectF);      // 四捨五入
rect = Rectangle.Truncate(rectF);   // 切り捨て(intでキャスト)
rect = Rectangle.Ceiling(rectF);    // 切り上げ

結果は

X Y Width Height
オリジナル 0.5 -1.5 10.5 5.2
Round 0 -2 10 5
Truncate 0 -1 10 5
Ceiling 1 -1 11 6

となります。

ここで気になるポイントとしては、Round(四捨五入)でX座標の0.5が0になってしまっています。(期待しているのは1)

 

この四捨五入に関しては

【C#】四捨五入
C#で、これまで四捨五入というと何となく double y = (int)(x + 0.5); とか、 double y = System.Math.Round(x); と、行っていたのですが、画像処理で補間処理を行う時に、座標を四捨五入し...

のページでも書いていますが、座標に関する値の四捨五入は、私は

int x, y;
y = (int)Math.Floor(x + 0.5);

のように書くようにしています。

 

以上のことから、RectangleFからRectangleへ変換するには

var rectF = new RectangleF(0.5f, -1.5f, 10.5f, 5.5f);
var rect = new Rectangle(
        (int)Math.Floor(rectF.X + 0.5),
        (int)Math.Floor(rectF.Y + 0.5),
        (int)Math.Floor(rectF.Width + 0.5),
        (int)Math.Floor(rectF.Height + 0.5)
    );

のように書くようにしています。

このときの結果は

X Y Width Height
オリジナル 0.5 -1.5 10.5 5.2
変換後 1 -1 11 5

となります。

 

せっかくRectangle構造体にRoundメソッドが用意されているのに、いまいち使えず、ベタに書いた方が良いようです。。

 

【参考ページ】

●.NET Frameworkのソースコード(Rectangle構造体)

Reference Source

●Microsoft Docs Rectangle構造体

Rectangle 構造体 (System.Drawing)
四角形の位置とサイズを表す 4 つの整数を格納します。

 

画像処理のためのC#へ戻る

コメント

タイトルとURLをコピーしました