如何绘制在C#Windows窗体可缩放图片 [英] How to Draw on Zoomable Image in C# windows Forms
问题描述
所以我实施一个项目,可以读取图像平移它,放大它,做其他的东西..一切都进行得很顺利,直到我试图实现与鼠标右键平局。
so am implementing a project that can read image pan it, zoom it and do other stuff.. everything was going well until i tried implementing a draw with right mouse button.
问题是,当我画一条线,该图像上显示的行不符合我画在屏幕上线,这意味着它的移位,我知道它的大小调整的,因为和图像的缩放,但当我借鉴的原始大小(图)图像和平移也行;我没有问题。
the problem is when i draw a line, the line that appears on the image does not correspond to the line i drew on screen, meaning its shifted and i know its because of the re-sizing and zooming of the image, but when i draw lines on the image with its original size(the image) and with panning also ; i have no problem.
这里的代码。
所以首先这里是我加载图片时,我单击浏览并选择图片
so first here is how i load the image when i click browse and select image
Myimage = new Bitmap(ImagePath);
resized = myImage.Size;
imageResize();
pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox_Paint);
pictureBox.Invalidate();
的
imageResize函数执行以下操作:
the imageResize function does the following:
void imageResize()
{
//calculated the size to fit the control i will draw the image on
resized.Height = someMath;
resized.Width = someMath;
}
在为pictureBox_Paint事件我写的事件处理程序,然后
then in the event handler for the pictureBox_Paint event i wrote:
private void pictureBox_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
// Create a local version of the graphics object for the PictureBox.
Graphics PboxGraphics = e.Graphics;
PboxGraphics.DrawImage(myImage, imageULcorner.X, imageULcorner.Y, resized.Width, resized.Height);
}
你可以看到调整大小后的大小不是原始图像的大小我这样做因为我想将图像显示在PictureBox控件集中填补现在的下一个部分是我的问题始于
as you can see the resized size is not the original image size i did this because i wanted the image to show on the picturebox control centralized and filled now the next part IS WHERE MY PROBLEM BEGINS
我要画用鼠标右键等图像线我实现pictureBox_MouseDown&安培; pictureBox_MouseUp事件处理程序
i have to draw lines on image using right mouse button so i implemented pictureBox_MouseDown & pictureBox_MouseUp event handlers
// mouse down event handler
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
else if (mouse.Button == MouseButtons.Right)
{
mouseDown = mouse.Location;
mouseDown.X = mouseDown.X - imageULcorner.X;
mouseDown.Y = mouseDown.Y - imageULcorner.Y;
draw = true;
}
}
下面是鼠标事件处理程序
here is the mouse up event handler
//Mouse UP
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
else if (mouse.Button == MouseButtons.Right)
{
if (draw)
{
mouseLocationNow.X = mouse.X - imageULcorner.X;
mouseLocationNow.Y = mouse.Y - imageULcorner.Y;
//
// get graphics object of the image ( the original not the resized)
// as the resized image only appears when i draw on the graphics of the
// pictureBox control
// i know the problem lies here but how can i fix it
//
Graphics image = Graphics.FromImage(myImage);
Pen pen = new Pen(Color.Red, 2);
image.DrawLine(pen, mouseLocationNow, mouseDown);
pictureBox.Invalidate();
}
draw = false;
}
所以最后我希望能够吸取重新大小形象,使之符合真实影像,并在那里我划清界线
感谢和抱歉的长期职位的屏幕,但这个问题已经快把我逼疯了。
so in the end i want to be able to draw on the re-sized image and make it correspond to the real image and also to the screen where i draw the line thanks and sorry for the long post but this problem has been driving me crazy.
推荐答案
下面是支持应用缩放能力的图片框
子不仅对图片
还要图形绘制在其表面。
Here is a PictureBox
subclass that supports the ability to apply zooming not only to the Image
but also to graphics you draw onto its surface.
它包括 SetZoom
功能通过缩放本身和矩阵放大
It includes a SetZoom
function to zoom in by scaling both itself and a Matrix.
它也有,你可以用它来计算 ScalePoint
功能来自像素的缩放的坐标,坐标,你的鼠标事件接收。
It also has a ScalePoint
function you can use to calculate the unscaled coordinates from the pixel coordinates you receive in the mouse events.
我们的想法是使用变换矩阵
缩放图形
对象将在油漆画
事件的任何像素。
The idea is to use a Transformation Matrix
to scale any pixels the Graphics
object will draw in the Paint
event.
我包括形式测试一些代码
I include a little code for the form for testing.
public partial class ScaledPictureBox : PictureBox
{
public Matrix ScaleM { get; set; }
float Zoom { get; set; }
Size ImgSize { get; set; }
public ScaledPictureBox()
{
InitializeComponent();
ScaleM = new Matrix();
SizeMode = PictureBoxSizeMode.Zoom;
}
public void InitImage()
{
if (Image != null)
{
ImgSize = Image.Size;
Size = ImgSize;
SetZoom(100);
}
}
public void SetZoom(float zoomfactor)
{
if (zoomfactor <= 0) throw new Exception("Zoom must be positive");
float oldZoom = Zoom;
Zoom = zoomfactor / 100f;
ScaleM.Reset();
ScaleM.Scale(Zoom , Zoom );
if (ImgSize != Size.Empty) Size = new Size((int)(ImgSize.Width * Zoom),
(int)(ImgSize.Height * Zoom));
}
public PointF ScalePoint(PointF pt)
{ return new PointF(pt.X / Zoom , pt.Y / Zoom ); }
}
下面是该做的测试代码的形式
Here is the code in the Form that does the testing:
public List<PointF> somePoints = new List<PointF>();
private void scaledPictureBox1_MouseClick(object sender, MouseEventArgs e)
{
somePoints.Add(scaledPictureBox1.ScalePoint(e.Location) );
scaledPictureBox1.Invalidate();
}
private void scaledPictureBox1_Paint(object sender, PaintEventArgs e)
{
// here we apply the scaling matrix to the graphics object:
e.Graphics.MultiplyTransform(scaledPictureBox1.ScaleM);
using (Pen pen = new Pen(Color.Red, 10f))
{
PointF center = new PointF(scaledPictureBox1.Width / 2f,
scaledPictureBox1.Height / 2f);
center = scaledPictureBox1.ScalePoint(center);
foreach (PointF pt in somePoints)
{
DrawPoint(e.Graphics, pt, pen);
e.Graphics.DrawLine(Pens.Yellow, center, pt);
}
}
}
public void DrawPoint(Graphics G, PointF pt, Pen pen)
{
using (SolidBrush brush = new SolidBrush(pen.Color))
{
float pw = pen.Width;
float pr = pw / 2f;
G.FillEllipse(brush, new RectangleF(pt.X - pr, pt.Y - pr, pw, pw));
}
}
下面是绘制出了几个点后的结果在四个不同的变焦设置相同点;在 ScaledPictureBox
显然是放置在自动滚屏面板
英寸该行显示了如何使用常规的绘图命令。
Here are the results after drawing a few points showing the same points in four different zoom settings; the ScaledPictureBox
is obviously placed in an AutoScroll-Panel
. The lines show how to use the regular drawing commands..
这篇关于如何绘制在C#Windows窗体可缩放图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!