🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

3回答

6271閲覧

【C#】 SizeModeがZoomのPictureBoxの画像内クリック位置が知りたい

JumpActionGames

総合スコア29

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Windows Forms

Windows Forms(WinForms)はMicrosoft .NET フレームワークに含まれる視覚的なアプリケーションのプログラミングインターフェイス(API)です。WinFormsは管理されているコードの既存のWindowsのAPIをラップすることで元のMicrosoft Windowsのインターフェイスのエレメントにアクセスすることができます。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2019/12/17 09:14

【C#】 SizeModeがZoomのPictureBoxの画像内クリック位置が知りたい

タイトルの通りで、SizeModeがZoomのPictureBoxの画像内クリック位置が知りたいです。
SizeModeがZoomなので、PictureBoxのクリック座標そのままではできません。

試したこと

Googleで調べてみたところ、OPENGLなどしか出てこなく、解決できなかったので、
ここに投稿しました。

ツールなど

IDE:VisualStudio2019
フレームワーク:.Net Frameworks
言語:C#
OS:Windows!0
アプリの種類: Windows Forms

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

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

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

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

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

BluOxy

2019/12/17 09:42 編集

勢いで回答してしまいましたが、「SizeModeがZoomのPictureBoxの画像内クリック位置」と「PictureBoxのクリック座標」の違いがよく分かりません。拡大・縮小をする前のクリック位置を取得したいのでしょうか。
YAmaGNZ

2019/12/17 11:47

Imageが拡大されて表示されている場合はまだいいかもしれませんが、縮小されて表示されている場合、PicTureBoxの座標から算出したとしても元画像の1点にならないのですがその場合はどうするのでしょうか?
TN8001

2019/12/17 12:17

やりたいことが本当はカーソル下の色の取得であれば、計算いらずで楽なソリューションがあります。
JumpActionGames

2019/12/18 00:35

SizeModeがZoomのPictureBoxのクリックイベントなどから得られるものは、PictureBox上の座標であり、拡大などされてるのでそのままだとダメです。 元の画像上での座標が知りたいです
guest

回答3

0

元々の画像の大きさと、表示している PictureBox の大きさの比を、クライアント座標に掛ける。
元の画像の大きさが100x100で、PictureBox の大きさが200x200で、マウスの座標が(50, 50)なら、画像上の点は(25,25)。
SizeMode を Zoom、Dock を Full にして Form におくと、Form のサイズ変更に追従して画像が拡大縮小される、と。そんな表示をしていて、クリックしたときの画像上の座標が知りたい、ということですよね?
Zoom だと、アスペクト比が維持されるので、画像が表示されていない部分が出てきます。その辺は注意して下さい。

投稿2019/12/18 12:51

Q71

総合スコア995

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

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

0

ベストアンサー

Select parts of a scaled image with different SizeMode valuesC# Helper
を参考にZoom専用で省コード化。
端数を切り捨てているからか気持ちずれているような気もする。

cs:Form1.cs

1using System; 2using System.Diagnostics; 3using System.Drawing; 4using System.Windows.Forms; 5 6namespace Questions230110 7{ 8 public partial class Form1 : Form 9 { 10 private System.Windows.Forms.PictureBox pictureBox1; 11 12 public Form1() 13 { 14 //InitializeComponent(); 15 this.pictureBox1 = new System.Windows.Forms.PictureBox(); 16 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 17 this.SuspendLayout(); 18 // 19 // pictureBox1 20 // 21 this.pictureBox1.ImageLocation = "https://upload.wikimedia.org/wikipedia/commons/1/1c/City_view_with_blue_sky.jpeg"; 22 this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; 23 this.pictureBox1.Location = new System.Drawing.Point(0, 0); 24 this.pictureBox1.Name = "pictureBox1"; 25 this.pictureBox1.Size = new System.Drawing.Size(800, 450); 26 this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 27 this.pictureBox1.TabIndex = 0; 28 this.pictureBox1.TabStop = false; 29 this.pictureBox1.Click += new System.EventHandler(this.pictureBox1_Click); 30 // 31 // Form1 32 // 33 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 34 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 35 this.ClientSize = new System.Drawing.Size(800, 450); 36 this.Controls.Add(this.pictureBox1); 37 this.Name = "Form1"; 38 this.Text = "Form1"; 39 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 40 this.ResumeLayout(false); 41 } 42 43 private void pictureBox1_Click(object sender, EventArgs e) 44 { 45 var p = ConvertCoordinates(((MouseEventArgs)e).Location); 46 Debug.WriteLine(p); 47 } 48 private Point ConvertCoordinates(Point location) 49 { 50 var x = location.X; 51 var y = location.Y; 52 var picH = pictureBox1.ClientSize.Height; 53 var picW = pictureBox1.ClientSize.Width; 54 var imgH = pictureBox1.Image.Height; 55 var imgW = pictureBox1.Image.Width; 56 57 int X0; 58 int Y0; 59 if(picW / (float)picH > imgW / (float)imgH) 60 { 61 var scaledW = imgW * picH / (float)imgH; 62 var dx = (picW - scaledW) / 2; 63 X0 = (int)((x - dx) * imgH / picH); 64 65 Y0 = (int)(imgH * y / (float)picH); 66 } 67 else 68 { 69 X0 = (int)(imgW * x / (float)picW); 70 71 var scaledH = imgH * picW / (float)imgW; 72 var dy = (picH - scaledH) / 2; 73 Y0 = (int)((y - dy) * imgW / picW); 74 } 75 76 if(X0 < 0 || imgW < X0 || Y0 < 0 || imgH < Y0) 77 { 78 return new Point(-1, -1); // 範囲外をどう表すのがいいか 79 } 80 81 return new Point(X0, Y0); 82 } 83 } 84}

今回は違ったようですが言及してしまったので、閲覧者向けにカーソル下の色の取得の楽なソリューション例。

cs:Form1.cs

1using System; 2using System.ComponentModel; 3using System.Drawing; 4using System.Windows.Forms; 5 6namespace Questions230110 7{ 8 public partial class Form1 : Form 9 { 10 private Bitmap bmp; 11 public Form1() => InitializeComponent(); 12 13 private void PictureBox1_MouseMove(object sender, MouseEventArgs e) 14 { 15 if(bmp == null) return; 16 panel1.BackColor = bmp.GetPixel(e.Location.X, e.Location.Y); 17 } 18 19 private void PictureBox1_LoadCompleted(object sender, AsyncCompletedEventArgs e) => DrawToBitmap(); 20 private void PictureBox1_Resize(object sender, EventArgs e) => DrawToBitmap(); 21 private void DrawToBitmap() 22 { 23 bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height); 24 pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle); 25 } 26 } 27}

cs:Form1.Designer.cs

1namespace Questions230110 2{ 3 partial class Form1 4 { 5 /// <summary> 6 /// 必要なデザイナー変数です。 7 /// </summary> 8 private System.ComponentModel.IContainer components = null; 9 10 /// <summary> 11 /// 使用中のリソースをすべてクリーンアップします。 12 /// </summary> 13 /// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param> 14 protected override void Dispose(bool disposing) 15 { 16 if(disposing && (components != null)) 17 { 18 components.Dispose(); 19 } 20 base.Dispose(disposing); 21 } 22 23 #region Windows フォーム デザイナーで生成されたコード 24 25 /// <summary> 26 /// デザイナー サポートに必要なメソッドです。このメソッドの内容を 27 /// コード エディターで変更しないでください。 28 /// </summary> 29 private void InitializeComponent() 30 { 31 this.panel1 = new System.Windows.Forms.Panel(); 32 this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); 33 this.pictureBox1 = new System.Windows.Forms.PictureBox(); 34 this.tableLayoutPanel1.SuspendLayout(); 35 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 36 this.SuspendLayout(); 37 // 38 // panel1 39 // 40 this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); 41 this.panel1.BackColor = System.Drawing.SystemColors.ActiveCaptionText; 42 this.panel1.Location = new System.Drawing.Point(375, 6); 43 this.panel1.Name = "panel1"; 44 this.panel1.Size = new System.Drawing.Size(50, 50); 45 this.panel1.TabIndex = 0; 46 // 47 // tableLayoutPanel1 48 // 49 this.tableLayoutPanel1.ColumnCount = 3; 50 this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 51 this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); 52 this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); 53 this.tableLayoutPanel1.Controls.Add(this.panel1, 1, 1); 54 this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Top; 55 this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); 56 this.tableLayoutPanel1.Name = "tableLayoutPanel1"; 57 this.tableLayoutPanel1.RowCount = 3; 58 this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 59 this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); 60 this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); 61 this.tableLayoutPanel1.Size = new System.Drawing.Size(800, 63); 62 this.tableLayoutPanel1.TabIndex = 3; 63 // 64 // pictureBox1 65 // 66 this.pictureBox1.BackColor = System.Drawing.Color.Black; 67 this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; 68 this.pictureBox1.ImageLocation = "https://upload.wikimedia.org/wikipedia/commons/1/1c/City_view_with_blue_sky.jpeg"; 69 this.pictureBox1.Location = new System.Drawing.Point(0, 0); 70 this.pictureBox1.Name = "pictureBox1"; 71 this.pictureBox1.Size = new System.Drawing.Size(800, 450); 72 this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 73 this.pictureBox1.TabIndex = 0; 74 this.pictureBox1.TabStop = false; 75 this.pictureBox1.LoadCompleted += new System.ComponentModel.AsyncCompletedEventHandler(this.PictureBox1_LoadCompleted); 76 this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox1_MouseMove); 77 this.pictureBox1.Resize += new System.EventHandler(this.PictureBox1_Resize); 78 // 79 // Form1 80 // 81 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 82 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 83 this.ClientSize = new System.Drawing.Size(800, 450); 84 this.Controls.Add(this.tableLayoutPanel1); 85 this.Controls.Add(this.pictureBox1); 86 this.Name = "Form1"; 87 this.Text = "Form1"; 88 this.tableLayoutPanel1.ResumeLayout(false); 89 ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 90 this.ResumeLayout(false); 91 92 } 93 94 #endregion 95 96 private System.Windows.Forms.PictureBox pictureBox1; 97 private System.Windows.Forms.Panel panel1; 98 private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; 99 } 100}

投稿2019/12/18 11:45

編集2023/07/17 12:47
TN8001

総合スコア9855

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

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

0

PictureBoxをクリックしたときのイベントでEventArgsオブジェクトからマウス座標が取得できます。

C#

1private void pictureBox1_Click(object sender, EventArgs e) 2{ 3 MouseEventArgs me = (MouseEventArgs)e; 4 Point coordinates = me.Location; 5}

参考:Read picture box mouse coordinates on click


質問文を読み直しました。

SizeModeがZoomのPictureBoxの画像内クリック位置

Imageクラスはフォームの部品ではないため、クリック位置を取得するプロパティは用意されていません。

画像の位置や拡大率を見ることで画像のクリック位置を取得している個人の記事がありました。こちらを参考にして解決できるかもしれません。ただ、少し邪道な気がします。

投稿2019/12/17 09:31

編集2019/12/17 10:29
BluOxy

総合スコア2663

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

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

BluOxy

2019/12/17 17:07

本当でした。補足ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問