【C#】RectangleRectangleFの相互変換

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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください