从图片框中的图像显示特定区域的放大图像 [英] Display magnified image of the specific area from the image in picturebox

查看:100
本文介绍了从图片框中的图像显示特定区域的放大图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#编程新手。我正在使用Windows应用程序,我有图片框从目录中加载图片。我想知道如何根据光标坐标显示特定区域的放大图像。就像光标悬停在图片上的特定字段上一样,它应该缩放该区域。



矩形R =新矩形(0,0,60000,480);

Pen cpen = new Pen(Color.Black,3);

Point mouseDownLoc;

public Form()

{

InitializeComponent();

//矩形屏幕= Screen.PrimaryScreen.WorkingArea;

// int w =宽度> = screen.Width? screen.Width :( screen.Width + Width)/ 2;

// int h = Height> = screen.Height? screen.Height :( screen.Height + Height)/ 2;

//this.Location = new Point((screen.Width - w)/ 2,(screen.Height - h)/ 2 );

//this.Size = new Size(w,h);

this.pictureBox2.MouseEnter + =(sender,args)=> this.pictureBox1.Show();

this.pictureBox2.MouseLeave + =(sender,args)=> this.pictureBox1.Hide();

this.pictureBox2.MouseMove + =(sender,args)=> DoMagnification();

}

private void DoMagnification()

{

try

{

//我们上次运行后清理

var oldImage = this.pictureBox1.BackgroundImage;

if(oldImage!= null )

oldImage.Dispose();



var position = this.pictureBox2.PointToClient(Cursor.Position);

var pboxWidth = this.pictureBox1.Width / 2;

var pboxHeight = this.pictureBox1.Height / 2;



位图image = new Bitmap(this.pictureBox2.Width,this.pictureBox2.Height);

// this.pictureBox2.DrawToBitmap(image,this.pictureBox2.Bounds);



//确保我们不会超出界限

Rectangle cloneRect = new Rectangle(Math.Max(position.X,0),Ma th.Max(position.Y,0),pboxWidth,pboxHeight);



if(cloneRect.Width + cloneRect.X> image.Width)

cloneRect.X - =(image.Width - cloneRect.Width);



if(cloneRect.Height + cloneRect .Y> image.Height)

cloneRect.Y - =(image.Height - cloneRect.Height);



System.Drawing .Imaging.PixelFormat格式=

image.PixelFormat;

//克隆Bitmap对象的一部分。

位图cloneBitmap = image.Clone (cloneRect,format);



//绘制Bitmap对象的克隆部分。

using(var graphics = CreateGraphics())

graphics.DrawImage(cloneBitmap,0,0);

this.pictureBox1.BackgroundImage = cloneBitmap;

this.pictureBox1.BackgroundImageLayout = ImageLayout .Zoom;



this.pictureBox1.Location = OffsetByAFewP ixels(位置);

}

catch(例外情况)

{

lblerror.Text = ex。消息;

}

}

私人Point OffsetByAFewPixels(点位置)

{

返回新点(location.X + 100,location.Y + 100);

}



private void pictureBox2_MouseEnter(对象发送者) ,EventArgs e)

{

// splitContainer1.Panel1.Focus();

尝试

{

int fx = 0;

int fy = 0;

fx = this.ClientRectangle.Left;

fy = this.ClientRectangle.Top;

Point startpoint = pictureBox1.PointToScreen(new Point(0,0));

Graphics G = this.CreateGraphics();

点位置=新Point(fx + pictureBox1.Left,fy + pictureBox1.Top);

Bitmap screenGrab = new Bitmap(pictureBox2.Image.Width,pictureBox2.Image.Height,System.Drawing.Imaging.PixelFormat.Format32bppArgb );

G = Graphics.FromImage(screenGrab);

G.CopyFromScreen(startpoint,new Point(0,0),pictureBox1.Size,CopyPixelOperation.SourceCopy);

pictureBox1.Image = screenGrab;

pictureBox1.BringToFront();

//pictureBox1.Visible = true;

}

catch(exception ex)

{

if(lblerror.Text ==)

{

lblerror.Text = ex.Message;

}

else

{

lblerror.Text + = ex.Message;

}

}

}

private void pictureBox2_MouseMove(object sender,MouseEventArgs e)

{

if(e.Button == MouseButtons.Left)< br $>
{

Point currentMousePos = e.Location;

int distanceX = currentMousePos.X - mouseDownLoc.X;

int distanceY = currentMousePos.Y - mouseDownLoc.Y;

int newX = pictureBox2.Location.X + distanceX;

int newY = pictureBox2.Location.Y + distanceY;

if(newX + pictureBox2.Image.Width< pictureBox2.Image.Width&& pictureBox2.Image.Width + newX> pictureBox2.Width)

pictureBox2.Location = new Point(newX,pictureBox2.Location.Y);

if(newY + pictureBox2.Image.Height< pictureBox2.Image .Height&& pictureBox2.Image.Height + newY> pictureBox2.Height)

pictureBox2.Location = new Point(pictureBox2.Location.X,newY);

}

试试

{

图形G = Graphics.FromImage(pictureBox1.Image);

// Picturebox1.CreateGraphics

GraphicsPath path = new GraphicsPath();

int L = 0;

int T = 0;

L = pictureBox1.Width +(eX * pictureBox2.Image.Width)/ pictureBox2.Width;

T = pictureBox1.Height / 2 + pictureBox2.Height - (eY * pictureBox2.Image。高度)/ pictureBox2.Height;

path.AddRectangle(R);

G.DrawPath(cpen,path);

G.SetClip(path,CombineMode.Replace);

//剪辑放大区域到屏幕捕获< br $>


G.DrawImage(pictureBox2.Image,pictureBox2.Width - 2 * L,T-pictureBox2.Height,pictureBox2.Image.Width + L,pictureBox2.Image.Height );

pictureBox1.Refresh();

}



catch(Exception ex)

{

if(lblerror.Text ==)

{

lblerror.Text = ex.Message;

}

其他

{

lblerror.Text + = ex.Message;

}

}

}

private void pictureBox2_MouseLeave(object sender,EventArgs e)

{

pictureBox1.Visible = false;

this.Refresh();

//离开区域时恢复视图

}

private void pictureBox2_MouseDown(object sender,MouseEventArgs e)

{

if(e.Button == MouseButtons.Left)

{

mouseDownLoc = e.Location;



}

}



我尝试了什么:



我已经尝试了另一个固定的图片框放大了mosue进入,但我是寻找可移动的放大镜

I am new to C# programming.I am working with windows application, I have picture Box to load image from the directory. I am trying to get some idea how can I display magnified image of particular area depending on the cursor coordinates. Like if the cursor hover on the particular field on the picture it should zoom that area.

Rectangle R = new Rectangle(0, 0, 60000, 480);
Pen cpen = new Pen(Color.Black, 3);
Point mouseDownLoc;
public Form()
{
InitializeComponent();
//Rectangle screen = Screen.PrimaryScreen.WorkingArea;
//int w = Width >= screen.Width ? screen.Width : (screen.Width + Width) / 2;
//int h = Height >= screen.Height ? screen.Height : (screen.Height + Height) / 2;
//this.Location = new Point((screen.Width - w) / 2, (screen.Height - h) / 2);
//this.Size = new Size(w, h);
this.pictureBox2.MouseEnter += (sender, args) => this.pictureBox1.Show();
this.pictureBox2.MouseLeave += (sender, args) => this.pictureBox1.Hide();
this.pictureBox2.MouseMove += (sender, args) => DoMagnification();
}
private void DoMagnification()
{
try
{
//clean up after our last run
var oldImage = this.pictureBox1.BackgroundImage;
if (oldImage != null)
oldImage.Dispose();

var position = this.pictureBox2.PointToClient(Cursor.Position);
var pboxWidth = this.pictureBox1.Width / 2;
var pboxHeight = this.pictureBox1.Height / 2;

Bitmap image = new Bitmap(this.pictureBox2.Width, this.pictureBox2.Height);
// this.pictureBox2.DrawToBitmap(image, this.pictureBox2.Bounds);

// ensure we dont go out of bounds
Rectangle cloneRect = new Rectangle(Math.Max(position.X, 0), Math.Max(position.Y, 0), pboxWidth, pboxHeight);

if (cloneRect.Width + cloneRect.X > image.Width)
cloneRect.X -= (image.Width - cloneRect.Width);

if (cloneRect.Height + cloneRect.Y > image.Height)
cloneRect.Y -= (image.Height - cloneRect.Height);

System.Drawing.Imaging.PixelFormat format =
image.PixelFormat;
// Clone a portion of the Bitmap object.
Bitmap cloneBitmap = image.Clone(cloneRect, format);

// Draw the cloned portion of the Bitmap object.
using (var graphics = CreateGraphics())
graphics.DrawImage(cloneBitmap, 0, 0);
this.pictureBox1.BackgroundImage = cloneBitmap;
this.pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;

this.pictureBox1.Location = OffsetByAFewPixels(position);
}
catch (Exception ex)
{
lblerror.Text = ex.Message;
}
}
private Point OffsetByAFewPixels(Point location)
{
return new Point(location.X + 100, location.Y + 100);
}

private void pictureBox2_MouseEnter(object sender, EventArgs e)
{
// splitContainer1.Panel1.Focus();
try
{
int fx = 0;
int fy = 0;
fx = this.ClientRectangle.Left;
fy = this.ClientRectangle.Top;
Point startpoint = pictureBox1.PointToScreen(new Point(0, 0));
Graphics G = this.CreateGraphics();
Point Position = new Point(fx + pictureBox1.Left, fy + pictureBox1.Top);
Bitmap screenGrab = new Bitmap(pictureBox2.Image.Width, pictureBox2.Image.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
G = Graphics.FromImage(screenGrab);
G.CopyFromScreen(startpoint, new Point(0, 0), pictureBox1.Size, CopyPixelOperation.SourceCopy);
pictureBox1.Image = screenGrab;
pictureBox1.BringToFront();
//pictureBox1.Visible = true;
}
catch( Exception ex)
{
if (lblerror.Text == "")
{
lblerror.Text = ex.Message;
}
else
{
lblerror.Text += ex.Message;
}
}
}
private void pictureBox2_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Point currentMousePos = e.Location;
int distanceX = currentMousePos.X - mouseDownLoc.X;
int distanceY = currentMousePos.Y - mouseDownLoc.Y;
int newX = pictureBox2.Location.X + distanceX;
int newY = pictureBox2.Location.Y + distanceY;
if (newX + pictureBox2.Image.Width < pictureBox2.Image.Width && pictureBox2.Image.Width + newX > pictureBox2.Width)
pictureBox2.Location = new Point(newX, pictureBox2.Location.Y);
if (newY + pictureBox2.Image.Height < pictureBox2.Image.Height && pictureBox2.Image.Height + newY > pictureBox2.Height)
pictureBox2.Location = new Point(pictureBox2.Location.X, newY);
}
try
{
Graphics G = Graphics.FromImage(pictureBox1.Image);
//Picturebox1.CreateGraphics
GraphicsPath path = new GraphicsPath();
int L = 0;
int T = 0;
L = pictureBox1.Width + (e.X * pictureBox2.Image.Width) / pictureBox2.Width;
T = pictureBox1.Height / 2 + pictureBox2.Height - (e.Y * pictureBox2.Image.Height) / pictureBox2.Height;
path.AddRectangle(R);
G.DrawPath(cpen, path);
G.SetClip(path, CombineMode.Replace);
// Clip Magnifying area to screen capture

G.DrawImage(pictureBox2.Image, pictureBox2.Width - 2*L, T- pictureBox2.Height, pictureBox2.Image.Width +L, pictureBox2.Image.Height);
pictureBox1.Refresh();
}

catch( Exception ex)
{
if (lblerror.Text == "")
{
lblerror.Text = ex.Message;
}
else
{
lblerror.Text += ex.Message;
}
}
}
private void pictureBox2_MouseLeave(object sender, EventArgs e)
{
pictureBox1.Visible = false;
this.Refresh();
//restore views when leaving area
}
private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
mouseDownLoc = e.Location;

}
}

What I have tried:

I have tried it with another picture box that is fixed to zoom on mosue enter, but I am looking for movable magnifier

推荐答案

您可以轻松制作已经用于放大的静态图片框,根据用户输入动态显示/隐藏/移动。比如onMouseEnter它可以移动到所需的位置(基于鼠标),onMouseMove它会跟随鼠标,而onMouseLeave它会隐藏。



只需为父图片框处理这些事件,它应该运行得很好。只需确保将放大的图片框从光标偏移一两个像素。如果你在光标下显示放大的图片框,你将进入一个循环,因为onMouseLeave事件将在放大的下方显示在父图片框上时触发,这将导致放大的图片框消失,这将触发onMouseEnter并显示它再次....



这是一个快速而肮脏的样本(提示:不要靠近表格的边缘)



只需创建一个带有DockStyle = Full的图片框(pictureBox1)和另一个Visible = false的小图片框。然后给pictureBox1一个背景图片。



You could easily make the static picturebox, that you are already using for magnification, dynamically show/hide/move based on user input. Such as onMouseEnter it could move to the desired location (based on the mouse), onMouseMove it would follow the mouse, and onMouseLeave it would hide.

Just handle those events for the parent picturebox, and it should work great. Just be sure to offset the Magnified picturebox from the cursor a pixel or two. If you make the magnified picturebox show under the cursor, you will get into a loop because the onMouseLeave event will fire on the parent picturebox when the magnified one shows underneath, which would cause the magnified picturebox to disappear, which would trigger onMouseEnter and show it again....

Here is a quick and dirty sample (hint: dont go near the edges of the form)

Just create a form with a picturebox (pictureBox1) that has DockStyle=Full, and another smaller picturebox with Visible=false. Then give pictureBox1 a Background image.

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.pictureBox1.MouseEnter += (sender, args) => this.pictureBox2.Show();

            this.pictureBox1.MouseLeave += (sender, args) => this.pictureBox2.Hide();

            this.pictureBox1.MouseMove += (sender, args) => DoMagnification();
        }

        private void DoMagnification()
        {
            // clean up after our last run
            var oldImage = this.pictureBox2.BackgroundImage;
            if (oldImage != null)
                oldImage.Dispose();

            var position = this.pictureBox1.PointToClient(Cursor.Position);
            var pboxWidth = this.pictureBox2.Width / 2;
            var pboxHeight = this.pictureBox2.Height / 2;

            Bitmap image = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);
            this.pictureBox1.DrawToBitmap(image, this.pictureBox1.Bounds);

            // ensure we dont go out of bounds
            Rectangle cloneRect = new Rectangle(Math.Max(position.X, 0), Math.Max(position.Y, 0), pboxWidth, pboxHeight);

            if (cloneRect.Width + cloneRect.X > image.Width)
                cloneRect.X -= (image.Width - cloneRect.Width);

            if (cloneRect.Height + cloneRect.Y > image.Height)
                cloneRect.Y -= (image.Height - cloneRect.Height);

            System.Drawing.Imaging.PixelFormat format =
                image.PixelFormat;
            // Clone a portion of the Bitmap object.
            Bitmap cloneBitmap = image.Clone(cloneRect, format);

            // Draw the cloned portion of the Bitmap object.
            using (var graphics = CreateGraphics())
                graphics.DrawImage(cloneBitmap, 0, 0);
            this.pictureBox2.BackgroundImage = cloneBitmap;
            this.pictureBox2.BackgroundImageLayout = ImageLayout.Zoom;

            this.pictureBox2.Location = OffsetByAFewPixels(position);
        }

        private Point OffsetByAFewPixels(Point location)
        {
            return new Point(location.X + 1, location.Y + 1);
        }
    }


是的,因为放大图像的边界超出原始范围,所以它会给出这些错误(为什么我提到避免角落:))。您将不得不添加一些代码来防止这种情况。该代码将类似于:



Yea it is giving those errors because the bounds of the magnified image is outside the bounds of the original (why I mentioned avoiding corners earlier :)). You will have to add a little bit of code to prevent that. That code would go something like:

Graphics G = this.CreateGraphics();

// Ensure we do not cross the left boundary
int gx = Math.Max(fx + pictureBox1.Left, 0);

// Ensure we do not cross the right boundary
gx = Math.Min(fx, pictureBox2.Width - pictureBox1.Width);

// Ensure we do not cross the top boundary
int gy = Math.Max(fy + pictureBox1.Top, 0);

// Ensure we do not cross the bottom boundary
gy = Math.Min(gy, pictureBox2.Height - pictureBox1.Height);

Point Position = new Point(gx, gy);





现在我还没有运行它,所以你可能需要做一些调试,但我们的想法是确保用于提取放大图像的边界始终在原始范围内。如果超出原始范围,您将看到 InvalidParameterException OutOfMemoryException BadImageFormatException (为什么这个弹出来,我永远不会理解......但确实如此),也许还有其他人。



所以你可能不得不玩它,但它应该只需最小的调整。



Now I haven't run this, so you may have to do some debugging, but the idea is to ensure that the bounds you use to extract the 'Magnified' image are always within the bounds of the original. If you go outside the bounds of the original, you will see InvalidParameterException, OutOfMemoryException, BadImageFormatException (why this one pops up, I'll never understand... but it does), and maybe some others.

So you will probably have to play around with it, but it should work with minimal tweaking.


这篇关于从图片框中的图像显示特定区域的放大图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆