質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

2120閲覧

vb.netでピクチャボックス内のイメージの左上の座標を取得したい

tada_tadaa

総合スコア111

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2021/12/25 02:57

Visual studio 2017のVBでフォーム内にピクチャボックスを設置し、画像を表示しています。ピクチャボックスはマウスで移動できるようになっています。
下の図で言うと、灰色の部分がフォームの領域で青い部分がピクチャボックスの領域になっており、ピクチャボックスの中にパソコンの画像が表示されています。

イメージ説明

ピクチャボックスを移動できるので、フォームのサイズを変更した場合などにピクチャボックスがフォームの外に行って、フォーム上に表示されなくなる事があったので、以下のようなソースでピクチャボックスがフォームの外に行った場合は、ピクチャボックスの座標をフォーム内に持ってくるようにしています。

vb

1 Sub FuncPictureBoxOverFix() 2 3 If PictureBox1.Top > Me.ClientSize.Height - 10 Then 4 PictureBox1.Top = Me.ClientSize.Height - 20 5 End If 6 7 If PictureBox1.Left > Me.ClientSize.Width - 10 Then 8 PictureBox1.Left = Me.ClientSize.Width - 20 9 End If 10 11 If PictureBox1.Right < 10 Then 12 PictureBox1.Left = -PictureBox1.Width + 20 13 End If 14 15 If PictureBox1.Bottom < 10 Then 16 PictureBox1.Top = -PictureBox1.Height + 20 17 End If 18 19 Me.Refresh() 20 End Sub

すると以下の図のようにピクチャボックスの端っこがフォーム内に表示されるようなりました。
イメージ説明

しかしフォームに表示されているのはピクチャボックスの青い領域でイメージ自体は表示されていません。
ピクチャボックス内のイメージ(パソコンの画像)の左上の座標がわかれば、イメージの端っこがフォームに表示されるように修正できるのですが、イメージの左上の座標を取得する方法が分かりません。
どのようにすればイメージの座標を取得できるでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vann_2921

2021/12/25 05:21

パソコンの画像はどのやってピクチャーボックスに表示しているのでしょうか? 画像をみるとピクチャーボックスを3等分した真ん中の位置にあるように見えますがどうやって位置を調整しているのでしょうか?
tada_tadaa

2021/12/25 06:27

PictureBox1.Image = System.Drawing.Image.FromFile(str) ↑の文で画像ファイルを読み込んでいます。strには画像ファイルのパスが格納されています。 >3等分した真ん中の位置にあるように見えますがどうやって位置を調整しているのでしょうか? 3等分した真ん中の位置にあるようにみえるのは、たまたまそうなっているだけです。マウスの右クリックでディレクトリ内の前の画像ファイル、左クリックで次の画像ファイルを呼び出し、マウスのホイールを動かすとピクチャボックスが拡大したり縮小したりする仕組みになってますが、例えば横長で縦が短い画像を呼び出すと、イメージの左と右のピクチャボックスの領域である青い領域は小さくなります。逆に縦が長く、横が短い縦長の画像を読み込むとイメージの左と右の青い領域は広くなります。また、マウスのホイールを動かしてピクチャボックスを拡大したり縮小したりすると、ピクチャボックス内のイメージも大きくなったり小さくなったりしますが、ある時はイメージの左右にピクチャボックスの青い領域があったり、イメージの上下に青い領域があったりと青い領域は変動します。 イメージはピクチャボックスの真ん中に表示されているように見えますが、僕の方で何か真ん中に表示されるように設定した記憶はないです。関係してるかもしれないこととしては、ピクチャボックスのプロパティである「SizeMode」を「Zoom」に設定した事と、ピクチャボックスのプロパティ「Anchor」を「None」に設定した事でしょうか。
guest

回答1

0

ベストアンサー

コード書いてみました。

ImageRectangleFromSizeMode で、画像の PictureBox におけるクライアント座標が分かるので、
PictureBox の RectangleToScreen メソッドでスクリーン座標に変換し、
Form の RectangleToClient で Form のクライアント座標に変換します。

VB

1Public Class Form1 2 3 Public Shared Function ImageRectangleFromSizeMode(pbox As PictureBox) As Rectangle 4 Dim result As Rectangle = DeflateRect(pbox.ClientRectangle, pbox.Padding) 5 If pbox.Image IsNot Nothing Then 6 Select Case pbox.SizeMode 7 8 Case PictureBoxSizeMode.Normal, PictureBoxSizeMode.AutoSize 9 result.Size = pbox.Image.Size 10 11 Case PictureBoxSizeMode.StretchImage 12 13 Case PictureBoxSizeMode.CenterImage 14 result.X += (result.Width - pbox.Image.Width) / 2 15 result.Y += (result.Height - pbox.Image.Height) / 2 16 result.Size = pbox.Image.Size 17 18 Case PictureBoxSizeMode.Zoom 19 Dim imageSize As Size = pbox.Image.Size 20 Dim ratio As Single = Math.Min(pbox.ClientRectangle.Width / imageSize.Width, 21 pbox.ClientRectangle.Height / imageSize.Height) 22 23 result.Width = imageSize.Width * ratio 24 result.Height = imageSize.Height * ratio 25 result.X = (pbox.ClientRectangle.Width - result.Width) / 2 26 result.Y = (pbox.ClientRectangle.Height - result.Height) / 2 27 End Select 28 End If 29 Return result 30 End Function 31 32 Private Shared Function DeflateRect(rect As Rectangle, padding As Padding) As Rectangle 33 rect.X += padding.Left 34 rect.Y += padding.Top 35 rect.Width -= padding.Horizontal 36 rect.Height -= padding.Vertical 37 Return rect 38 End Function 39 40 Private Sub PictureBox1_LocationChanged(sender As Object, e As EventArgs) Handles PictureBox1.LocationChanged 41 Dim pbox As PictureBox = DirectCast(sender, PictureBox) 42 Dim r As Rectangle = ImageRectangleFromSizeMode(pbox) 43 Me.Text = RectangleToClient(pbox.RectangleToScreen(r)).ToString() 44 End Sub 45 46 <System.Runtime.InteropServices.DllImport("User32.dll")> 47 Private Shared Function SendMessage(hWnd As IntPtr, uMsg As Integer, wParam As IntPtr, lParam As IntPtr) As IntPtr 48 End Function 49 50 <System.Runtime.InteropServices.DllImport("User32.dll")> 51 Private Shared Function SetCapture(hwnd As Integer) As Boolean 52 End Function 53 54 <System.Runtime.InteropServices.DllImport("User32.dll")> 55 Private Shared Function ReleaseCapture() As Boolean 56 End Function 57 58 Private Const WM_SYSCOMMAND As Integer = &H112 59 Private Const SC_MOVE As Integer = &HF010 60 61 Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown 62 Dim pbox As PictureBox = DirectCast(sender, PictureBox) 63 SetCapture(pbox.Handle) 64 ReleaseCapture() 65 SendMessage(pbox.Handle, WM_SYSCOMMAND, SC_MOVE Or 2, 0) 66 End Sub 67 68End Class 69 70PictureBox をドラッグして動かすと Form のタイトルバーに座標が表示されます。

投稿2021/12/25 09:36

KOZ6.0

総合スコア2626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tada_tadaa

2021/12/25 14:38

回答ありがとうございます。 教えていただいたプログラムを試してみた所、FormのタイトルバーにX座標、Y座標、Width、Heightが表示されました。ピクチャボックス内に画像を読み込んでマウスでピクチャボックスを動かして、フォームの角に合わせたりしていると、ピクチャボックス自体はY座標が0、X座標が0の所に置いていたとしても、タイトルバーにはX=0,Y=0とは表示されずに、イメージの座標が表示されている事を確認できました。 また、WindowsAPIを使ってピクチャボックスをマウスで動かせるようにする技術や、画像の大きさとピクチャボックスの大きさから実際に表示されるイメージの大きさと座標を求める計算式、KOZ6.0様が教えてくれたリンク先に、C#ではありましたが内部の挙動らしきものが載っていたりと、とても勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問