1

写真などのビットマップをロードした PictureBox があります。

Picture1.Image = new Bitmap("photo.bmp");

イベントでPicture1_Paint()は、写真に線を描きます。

e.Graphics.DrawLine(myPen, pointA, pointB);

ここで、クリックされたピクセルの RGB 情報を表示したいと思います。

Bitmap bitmap = (Bitmap) Picture1.Image;  /* Making sure I'm using the image being displayed */
Color color = bitmap.GetPixel(e.X, e.Y);
lblSelectedColor.Text = color.R.ToString() + ", " + color.G.ToString() + ", " + color.B.ToString();

問題は、取得した RGB 値が、元の写真のそのピクセルの色であり、線画が含まれていないことです。たとえば、空に太い赤い線が描かれている場合、その赤い線をクリックすると、写真から空色の色が得られます。

描いた線や楕円など、PictureBox に表示されているものの色情報を取得したいと考えています。

4

3 に答える 3

1

イベントまたはメソッドを介してコントロールが占有する画面に描画することと、コントロール内に表示されるビットマップに描画することには違いがあります。前者を実行しますが、後者からピクセルを取得しようとしています。PaintOnPaint

Paintイベントに描画する代わりにGraphics、画像用のオブジェクトを作成し、それを直接描画する必要があります。次に、画像をImage画像ボックスのプロパティに割り当てます。

たとえば、私の頭の上から:

Image image = /* ... */;
using (Graphics g = Graphics.FromImage(image))
{
    g.DrawLine(myPen, pointA, pointB);
}
picture1.Image = image;

次に、画像ボックス内GetPixelのオブジェクトに対して行うと、Image描画した線のピクセル値が取得されます。

于 2013-03-20T02:33:32.913 に答える
1

Bob Powell の Eye Dropperを使用します。コードは次のとおりです。

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
 

namespace pixelcolor
{
  /// <summary>
  /// Summary description for Form1.
  /// </summary>
  public class Form1 : System.Windows.Forms.Form
  {
 
 
    [DllImport("Gdi32.dll")]
    public static extern int GetPixel(
    System.IntPtr hdc,    // handle to DC
    int nXPos,  // x-coordinate of pixel
    int nYPos   // y-coordinate of pixel
    );
 
    [DllImport("User32.dll")]
    public static extern IntPtr GetDC(IntPtr wnd);
 
    [DllImport("User32.dll")]
    public static extern void ReleaseDC(IntPtr dc);
 
 
    private System.Windows.Forms.Panel panel1;
    private System.Timers.Timer timer1;
 
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.Container components = null;
 
    public Form1()
    {
      //
      // Required for Windows Form Designer support
      //
      InitializeComponent();
      this.SetStyle(ControlStyles.ResizeRedraw,true);
    }
 
    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    protected override void Dispose( bool disposing )
    {
      if( disposing )
      {
        if (components != null)
        {
          components.Dispose();
        }
      }
      base.Dispose( disposing );
    }
 
    #region Windows Form Designer generated code
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.panel1 = new System.Windows.Forms.Panel();
      this.timer1 = new System.Timers.Timer();
      ((System.ComponentModel.ISupportInitialize)(this.timer1)).BeginInit();
      this.SuspendLayout();
      //
      // panel1
      //
      this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
      this.panel1.Location = new System.Drawing.Point(216, 8);
      this.panel1.Name = "panel1";
      this.panel1.Size = new System.Drawing.Size(64, 56);
      this.panel1.TabIndex = 0;
      //
      // timer1
      //
      this.timer1.Enabled = true;
      this.timer1.SynchronizingObject = this;
      this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);
      //
      // Form1
      //
      this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
      this.BackColor = System.Drawing.Color.White;
      this.ClientSize = new System.Drawing.Size(292, 273);
      this.Controls.Add(this.panel1);
      this.Name = "Form1";
      this.Text = "Form1";
      this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
      ((System.ComponentModel.ISupportInitialize)(this.timer1)).EndInit();
      this.ResumeLayout(false);
 
    }
    #endregion
 
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
      Application.Run(new Form1());
    }
 
    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
      Random r=new Random(1);
 
      for(int x=0;x<100;x++)
      {
        SolidBrush b=new SolidBrush(Color.FromArgb(r.Next(255),r.Next(255),r.Next(255)));
        e.Graphics.FillRectangle(b,r.Next(this.ClientSize.Width),r.Next(this.ClientSize.Height),r.Next(100),r.Next(100));
      }
    }
 
    private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
      Point p=Control.MousePosition;
      IntPtr dc=GetDC(IntPtr.Zero);
      this.panel1.BackColor=ColorTranslator.FromWin32(GetPixel(dc,p.X,p.Y));
      ReleaseDC(dc);
    }
  }
}
 

PictureBox または独自のフォームで色をサンプリングする場合は、そのオブジェクトの DC を取得するだけです。これは、CreateGraphics、Graphics.GetHdc、および Graphics.ReleaseHdc を使用して実現できます。以下のリストは、フォームからピクセルの色を取得するために使用できる MouseMove ハンドラーを示しています。

protected override void OnMouseMove(MouseEventArgs e)
{
  Graphics g=this.CreateGraphics();
  IntPtr myDC=g.GetHdc();
  Color c=ColorTranslator.FromWin32(GetPixel(myDC,e.X,e.Y));
  g.ReleaseHdc(myDC);

  this.panel1.BackColor=c;
}
于 2013-03-20T02:55:23.723 に答える
1

上記のジェレミーの答えを変更して、それを機能させる必要がありました。ReleaseDC のプロトタイプは、彼が投稿したものとは異なるようです。これは私のために働いた:

    [DllImport("Gdi32.dll")]
    public static extern int GetPixel(
        System.IntPtr hdc,    // handle to DC
          int nXPos,  // x-coordinate of pixel
          int nYPos   // y-coordinate of pixel
     );

    [DllImport("User32.dll")]
    public static extern IntPtr GetDC(IntPtr wnd);

    [DllImport("User32.dll")] 
    public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

    //For best results, use a component like a Panel and use it's handle (panel1.Handle) and e.X and e.Y on a component's MouseDown event
    private Color GetColorAtPoint(Point? p = null, IntPtr? handle = null)
    {
        var hwnd = handle ?? IntPtr.Zero; // Handle;
        Point point = p ?? MousePosition;
        var dc = GetDC(hwnd);
        Color c = ColorTranslator.FromWin32(GetPixel(dc, point.X, point.Y));
        ReleaseDC(hwnd, dc);
        return c;
    }
于 2020-12-12T05:23:20.333 に答える