Rectangle(Bitmap)の幅と高さ

このQ&Aのポイント
  • Rectangle構造体で指定するBitmapの範囲は、(Rectangle.Left + Rectangle.Width - 1)×(Rectangle.Top + Rectangle.Height - 1)の範囲となる。
  • BitmapのWidthとHeightも同様に指定されるが、実際の動作には影響はほとんどない。
  • LockBitsとUnlockBitsを使用してBitmapのpixel情報をコピーするコードを書く際に、Rectangleで指定する範囲やBitmapの幅と高さについて気になることがある。
回答を見る
  • ベストアンサー

Rectangle(Bitmap)の幅と高さ

 以下、VBの記法で書きます。Windows10,.NETのGDI+を使用しています。  今まであまり気にしていなかったのですが、今回LockBitsとUnLockBitsを使用してBitmapのpixel情報をCopyするコードを書く事になり、急に気になり出しました。  LockBitsを使用する際、Rectangle構造体で読みだすBitmapの範囲を指定します。Rectangleが指定する実際のpixelですが、   (Rectangle.Left + Rectangle.Width - 1)×(Rectangle.Top + Rectangle.Height - 1) の範囲かな?、と思いました。例えば、   Dim Rect as Rectangle = New Rectangle(1, 1, 0, 0) などとやると、Rectは空になるし、(1, 1)一点を表すRectangleなら、   Dim Rect as Rectangle = New Rectangle(1, 1, 1, 1) なので・・・。  BitmapのWidthとHeightについても同様かと思います。実際の動作には余り影響しないのですが、気になったもので・・・。

質問者が選んだベストアンサー

  • ベストアンサー
  • shibucin
  • ベストアンサー率38% (16/42)
回答No.2

Rectangle構造体の引数で指定される幅と高さは、指定された左上隅の座標を始点として、指定された幅と高さの長方形領域を表します。したがって、引数で指定された値は、始点から幅または高さ分だけ右に進んだ位置や下に進んだ位置を表します。つまり、Rectangle.WidthとRectangle.Heightは、それぞれ幅と高さの値であり、Rectangle.LeftとRectangle.Topは、始点のX座標とY座標を表します。したがって、以下のようにRectを指定することができます。 Dim Rect as Rectangle = New Rectangle(1, 1, 1, 1) これは、左上隅が座標(1, 1)の1x1ピクセルの長方形を表します。Bitmapの幅と高さも同様に、Bitmap.WidthとBitmap.Heightは、それぞれビットマップの幅と高さを表します。したがって、Rectangle構造体で指定された長方形領域がBitmapの領域を超えることがないようにする必要があります。

ddtddtddt
質問者

お礼

>・・・Rectangle構造体で指定された長方形領域がBitmapの領域を超えることがないようにする必要があります。  まさにBinding矩形を作る時に、1pixel分どうしよう?という話でした。最初はアンマネージメモリでの話なので、Bitmapをはみ出すRectangleでもいいんじゃねっ?、って事で気楽に動かしたら、実行時エラーになりました(^^;)。  考え方が確認できました。ありがとうございます。

その他の回答 (1)

  • f272
  • ベストアンサー率46% (8008/17113)
回答No.1

BitmapクラスのLockBitsメソッドに渡すRectangle構造体のWidth,Heightプロパティは画素数で指定するようです。通常はectangle構造体のWidth, Heightプロパティは距離=画素数-1となっています。 PictureBoxなどのコントロールや、BitmapクラスのWidth, Heightプロパティはやはり画素数です。

ddtddtddt
質問者

お礼

 そのものずばりの回答、ありがとうございます。  ただベストアンサーは、色々気を使って頂いた#2さんへ送りたいと思います。ご容赦下さい。

関連するQ&A

  • bitmapの宣言

    こんばんわ。 bitmapの宣言を最初に行い、途中のサブルーチン内で大きさの変更を行いたいのですが、可能でしょうか? Public Class Form1 Dim BMP As New Bitmap(300, 200) Private Sub このなかで、300*200の指定を行いたいです。 End Sub ちなみに、 Public Class Form1 Dim BMP As Bitmap Private Sub BMP = New Bitmap(300, 200) End Sub などと悪あがきをしましたがダメでした。 良い解決策を教えてください。よろしくお願いします。 バージョンは、.NET 2005です。

  • ユーザー定義オブジェクト

    現在、ユーザー定義オブジェクトについて勉強しています。 以下は本からの抜粋です。 //コンストラクタを定義する。 //thisで参照するオブジェクトの初期化法に注目   function Rectangle(w,h) { this.width=w; this.height=h; } //コンストラクタを呼び出して2つの長方形オブジェクトを生成する。 //widthとheightをコンストラクタに渡して、それぞれの新しい //オブジェクトを適切な形で初期化するやり方に注目 var rect1=new Rectangle(2,4); var rect2=new Rectangle(8.5,11); ★質問★ this.width=w; this.height=h; var rect1=new Rectangle(2,4); var rect2=new Rectangle(8.5,11); この2箇所で行っている「初期化」という作業の意味がよく分かりません。 また、ユーザー定義オブジェクトの概念についていまいちイメージ がつかめていません(特にthisとnewを使用している意図など) ご教授いただきたく、よろしくお願いします。

  • C#でフォームのコピーをしたい

    最近C#を始めたのですが、フォームをコピーする際に Bitmap myBmp = new Bitmap(this.Width, this.Height); this.DrawToBitmap(myBmp, new Rectangle(0, 0, this.Width, this.Height)); Clipboard.SetDataObject(myBmp, false); といった風にコピーをしていたのですが、これではフォーム全体がコピーされ、縁ができてしまいます。範囲指定してフォームコピーをする方法はないでしょうか。

  • VB2010で、キャプチャしたものを貼り付けるにはどうしたらいいのでし

    VB2010で、キャプチャしたものを貼り付けるにはどうしたらいいのでしょうか。 ご存知の方教えてください。よろしくお願いします。 ???の部分のコードがわかりません。 'キャプチャする Dim copy_bmp As New Bitmap(Me.PictureBox1.Width, Me.PictureBox1.Height) Me.DrawToBitmap(copy_bmp, New Rectangle(0, 0, Me.PictureBox1.Width, Me.PictureBox1.Height)) PictureBox3 = copy_bmp??? copy_bmp.Dispose()

  • Bitmapのディスク容量

     以下、VBの記法で書きます。Windows10,.NETのGDI+を使用しています。  PixelFormat が Format32bppArgb のBitmapを作成し、描画処理が終わった後、Bitmap.Save(パス名)で保存します。  Bitmapは1250×1250(pixel)なので、そのディスク容量は、   1250×1250×4(byte)=6104 KB=6 MB くらいと思ってました。ところが保存してみると、60 KBくらい・・・。  読みだして表示するとちゃんと保存されてるので、これはこれであり難い事なのですが、どうして?、という質問です(^^;)。  PixelFormat が Format32bppArgb の場合は初期化時に、各pixelの(A,R,G,B) は (A,R,G,B)=(0,0,0,0)であり、例えばPictureBox の BackColor との兼ね合いで、(R,G,B)=(0,0,0)(黒)はDefaultで透過色になってるので、ディスク保存時には、pixel位置を表すIndex付きでpixel情報が圧縮されて保存されるのかしら?、などと想像したわけです。  たんに気になるので、どうなってるか知りたいだけです。ネットで検索してもBitmapの大きさは、画素数×4 byte という記事しか出てこないので・・・(^^;)。  関連する検索キーワードでも良いので、教えてもらえませんか。

  • VB2005 でビットの深さ8の画像を処理したい。

    VB2005を使って簡単な画像処理のツールを制作しています。 処理内容は、画像ファイル(jpg)を読み込み、画像を縦に区切って 左側と右側を別のファイルに保存する、という処理です。 縦に区切る位置(x 座標)は、自由に指定できます。 上記のような処理を「任意の解像度(0~300 dpi)、ビットの深さ 8 」 の画像で行うには、どのようにしたらよいのでしょうか。 (ビットの深さ 8 の image からは Graphics オブジェクトを  作ることができず、そのため、読み込んだ画像の解像度を  保てませんでした。) ビットの深さが 24 の画像は、以下のようにして問題なく動きました。 "scanfile01.jpg" は、 解像度 300dpi / ビットの深さ 24 / 縦1500 × 横1200 ピクセル の画像ファイルです。 --------------- private sub splitImage()  '画像(src)の読み込み  Dim fs As New IO.FileStream("scanfile01.jpg", _     IO.FileMode.Open)  Dim src As Image = Image.FromStream(fs, False, False)  Dim srcG As Graphics = Graphics.FromImage(src) '解像度の取得用  'src を分割する位置(x座標)  '(横幅1500 の scanfile01.jpg を左右半分に分ける)  Dim cutx As Integer = 750   'src の左側を格納する Bitmap を新規作成  '(src の解像度を引き継ぐ)  Dim destLeft As Image = New Bitmap(cutx, src.Height, srcG)  Dim rect As New Rectangle(0, 0, cutx, src.Height)  Dim destLeftG As Graphics = Graphics.FromImage(destLeft)  Dim rect As New Rectangle(0, 0, cutx, src.Height)  destLeftG.DrawImage(src, 0, 0, rect, GraphicsUnit.Pixel)  'src の左側をファイルに保存  destLeft.Save("scanfile01-left.jpg" _         , System.Drawing.Imaging.ImageFormat.Jpeg)  destLeft.Dispose()  destLeftG.Dispose()  'src の右側を格納する Bitmap を新規作成  ~省略~  srcG.Dispose()  src.Dispose()  fs.Dispose() End Sub ---------------- ビットの深さ 8 の画像を読み込むと、実行時に  Dim srcG As Graphics = Graphics.FromImage(src) '解像度の取得用 の部分で「インデックス付きのピクセルから Graphics オブジェクトを作成できません」というエラーが発生します。 そこで、解像度は引き継がずに、以下のように変更してみました。 ・srcG の定義文を削除 ・destLeft の定義時に解像度は指定せず、以下のように変更   Dim destLeft As Image = New Bitmap(cutx, src.Height) すると、エラーは発生せずファイルが作成されましたが、 解像度が引き継がれずに元の画像よりずっと小さな画像になって 作成されていました。 (作成されたファイルを開くと、イメージが小さくなった分、  黒い隙間ができていました。) 300 dpi の画像を読み込んだので、VB2005 で作成される?Bitmap のデフォルトの解像度 96 dpi に変換される際にピクセル抜けが 発生して画像が小さくなったのだと思います。 ビットの深さ 8 の画像を半分に区切ってファイルに保存する方法は ないのでしょうか。また、任意の解像度でピクセル抜けが 発生しないようにしたいです。

  • (VB.net)画像の一部を切り取って,拡大・縮小したい

    内容を見ていただき,ありがとうございます。 タイトルのままですが,PictureBoxに画像を出して,その一部を切り取ったうえで拡大・縮小させるプログラムを作成しています。 今のところ,画像の一部を切り出すことはできたのですが,これを拡大・縮小させる方法をご存じないでしょうか。画像の一部を切り出すソースは以下のとおりです。 まず,フォームにピクチャボックス(PictureBox1)とコマンドボタン(Button1)を配置し,ソリューションを置いているフォルダ内のbinフォルダにWinter.jpg(WinXPのマイピクチャに入っているものです)を入れておきます。次に,Button1のコードとして,以下のものを打ち込みました。 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'Bitmapオブジェクトの作成(切り取り元画像の指定) Dim bmap = New Bitmap("winter.jpg") '切り取る範囲をRectanleで指定 Dim rect As New Rectangle(10, 20, 100, 200) 'PictureBox1のGraphicsオブジェクトの作成 Dim g As Graphics = PictureBox1.CreateGraphics() '元の画像の指定部分を切り取ってPictureboxの左上隅(x,y = 0,0)に表示する.単位はピクセル. g.DrawImage(bmap, 0, 0, rect, GraphicsUnit.Pixel) 'Graphicsオブジェクトを破棄 g.Dispose() End Sub 以上です。 おそらく,DrawImageの部分を変えればいけるのではないかと思われるのですが,いかがでしょうか。ご助言よろしくお願いいたします。

  • ユーザーコントロールのDrawToBitmap

    vb.net(VisualStudio2015)で作成したユーザーコントロール内の画面を「DrawToBitmap」で取得しフォーム内に表示したいのですが上手く表示できません。もしご存知の方がいましたらご教授して頂けますと助かります。宜しくお願い致します。 Private SecondScreen as New UserControl1 'ユーザーコントロール内の画面を取得 Dim mBitmap as New Bitmap(SecondScreen.Width,SecondScreen.Height) SecondScreen.DrawToBitmap(mBitmap,New Rectangle(0,0,SecondScreen.Width,SecondScreen.Height)) . . . '取得した画面をフォームに表示 Dim g as Graphics = e.Graphics g.DrawImage(mBitmap,new Rectangle(0,0,SecondScreen.Width,SecondScreen.Height)) いくつか省略箇所がありますが、上記の方法ですとユーザーコントロール内の画面が取得できなく、「SecondScreen.Visible=True」で一度表示させてから取得すると表示されます。 フォーム内にユーザーコントロールを張り付けて表示させるのではなく、一度「DrawToBitmap」で取得させてから表示させたいのです。 お手数ですが、ご教授お待ちしています。 宜しくお願い致します。

  • bitmapクラスをiconクラスに変換する方法

    bitmapクラスをiconクラスに変換する方法 bitmapクラスをiconクラスに変換する方法 今、画像変換ソフトをVisual Basic 2010 Express Editionで作っているのですがbitmapクラスをiconクラスに変換する方法が分かりません。 GetHiconを使って変換する方法を試してみたのですがアイコンが16色になってしまい画像が変わってしまいます。 変換ソフトで使用するBitmapをIconに変換する関数を作ったのですが変換するところで止まっています。 Public Function convert_to_ico(ByVal image As Bitmap) As Icon Dim loadimage As Bitmap = New Bitmap(16, 16, PixelFormat.Format24bppRgb) Dim draw As Graphics = Graphics.FromImage(loadimage) draw.DrawImage(image, 0, 0) Dim returnico As Icon Return returnico End Function 申し訳ありませんが、宜しくお願いします。

  • .bmp.saveがうまくいかない

    お世話になります。 自身で.DrawLineでピクチャーボックスに描画した線を含めて画像をbmp.saveで保存したいのですが、もとのピクチャーボックスしかsaveされません。 今行っているソースは以下の通りです。 Private Sub GraphImgSave() Dim bmp As New Bitmap(Pic_GraphHere.Width, Pic_GraphHere.Height) Dim Mtop As Integer Dim Mleft As Integer Mtop = 250 'Mleft = 10 'キャプチャする Me.DrawToBitmap(bmp, New Rectangle(Mleft, Mtop, Pic_GraphHere.Width, Pic_GraphHere.Height)) 'ファイルに保存する Try bmp.Save("d:\graphimg\curelastgraph.bmp") Catch ex As Exception MsgBox("保存できませんでした" & vbCrLf & ex.Message) End Try '後始末 bmp.Dispose() End Sub 宜しくお願いします

専門家に質問してみよう