あまりやる事は無いのですが、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#へ戻る
コメント