通过onPaint方法获取图像绘制的像素值



我正在开发一个自定义的C#用户控件WinForm,以在背景上显示图像,并在用鼠标缩放时显示滚动条。为此,我否决了OnPaint方法。在它中,如果我加载了一个图像,根据一些参数,我知道源和目标矩形的大小。同样,我知道缩放时保持屏幕左上角的比例和平移方式。对于缩放,我使用滚动鼠标事件来更新缩放工厂。

这是我的代码与这个重写方法有关。

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// Draw image
if(image != null)
{
// 
Rectangle srcRect, destRect;
Point pt = new Point((int)(hScrollBar1.Value/zoom), (int)(vScrollBar1.Value/zoom));
if (canvasSize.Width * zoom < viewRectWidth && canvasSize.Height * zoom < viewRectHeight)
srcRect = new Rectangle(0, 0, canvasSize.Width, canvasSize.Height);  // view all image
else if (canvasSize.Width * zoom < viewRectWidth)
srcRect = new Rectangle(0, pt.Y, canvasSize.Width, (int)(viewRectHeight / zoom));  // view a portion of image but center on width
else if (canvasSize.Height * zoom < viewRectHeight)
srcRect = new Rectangle(pt.X, 0, (int)(viewRectWidth / zoom), canvasSize.Height);  // view a portion of image but center on height
else
srcRect = new Rectangle(pt, new Size((int)(viewRectWidth / zoom), (int)(viewRectHeight / zoom)));   // view a portion of image

destRect = new Rectangle((int)(-srcRect.Width/2),
(int)-srcRect.Height/2,
srcRect.Width,
srcRect.Height); // the center of apparent image is on origin

Matrix mx = new Matrix(); // create an identity matrix
mx.Scale(zoom, zoom); // zoom image
// Move image to view window center
mx.Translate(viewRectWidth / 2.0f, viewRectHeight / 2.0f, MatrixOrder.Append);
// Display image on widget
Graphics g = e.Graphics;
g.InterpolationMode = interMode;
g.Transform = mx;
g.DrawImage(image, destRect, srcRect, GraphicsUnit.Pixel);
}
}

我的问题是,当我使用WinForm的MouseMove覆盖方法时,如何获得像素值?

我想我理解这只是在使用PaintEventArgs的方法中可能的,但我不确定如何处理它。我尝试了很多事情,但现在我得到的更好的方法是使用屏幕上的鼠标位置,并在原始位图中找到这些"的像素值;错误的";坐标。我无法将屏幕上的这个相对位置与此处图像显示像素的实际坐标联系起来。也许有一种方法可以";只是";得到像素值没有通过我用于绘制方法的图像位图?也许不是。

提前感谢您的帮助。顺致敬意,

我不能完全理解您的绘图代码,但您可以对鼠标坐标进行逆变换。因此,您可以将鼠标坐标转换回原点,并按1/zoom缩放。这个简单的过程提供了图像空间坐标。

我提供了一个带有自己绘图代码的示例代码(而不是您的代码/算法(,但它仍然可以给您提供逆变换的想法。它非常简单,所以看看示例代码。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GetPixelFromZoomedImage
{
public partial class MainForm : Form
{
public Form1()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
InitializeComponent();
}
private float m_zoom = 1.0f;
private Bitmap m_image;
private Point m_origin = Point.Empty;
private Point m_delta = Point.Empty;
private SolidBrush m_brush = new SolidBrush(Color.Transparent);
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.TranslateTransform(m_origin.X, m_origin.Y);
g.ScaleTransform(m_zoom, m_zoom); 
g.DrawImageUnscaled(m_image, Point.Empty); 
g.ResetTransform();
g.FillRectangle(m_brush, ClientSize.Width - 50, 0, 50, 50);
base.OnPaint(e);
}
protected override void OnHandleCreated(EventArgs e)
{
m_image = (Bitmap)Image.FromFile("test.png");
base.OnHandleCreated(e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
m_delta = new Point(m_origin.X - e.X, m_origin.Y - e.Y);
}
base.OnMouseDown(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
m_origin = new Point(e.X + m_delta.X, e.Y + m_delta.Y); 
Invalidate();
}
int x = (int)((e.X - m_origin.X) / m_zoom);
int y = (int)((e.Y - m_origin.Y) / m_zoom);
if (x < 0 || x >= m_image.Width || y < 0 || y >= m_image.Height)
return;

m_brush.Color = m_image.GetPixel(x, y); 
Invalidate();
base.OnMouseMove(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
}
protected override void OnMouseWheel(MouseEventArgs e)
{
float scaleFactor = 1.6f * (float)Math.Abs(e.Delta) / 120;
if(e.Delta > 0) 
m_zoom *= scaleFactor; 
else
m_zoom /= scaleFactor;
m_zoom = m_zoom > 64.0f ? 64.0f : m_zoom;
m_zoom = m_zoom <  0.1f ?  0.1f : m_zoom;
Invalidate();
base.OnMouseWheel(e);
}

}
}

最新更新