あまりやる事は無いのですが、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#】四捨五入
続きを見る
のページでも書いていますが、座標に関する値の四捨五入は、私は
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構造体)
https://referencesource.microsoft.com/#System.Drawing/commonui/System/Drawing/Rectangle.cs
●Microsoft Docs Rectangle構造体
https://docs.microsoft.com/ja-jp/dotnet/api/system.drawing.rectangle
←画像処理のためのC# へ戻る