c# - zoom an image in a second picturebox following cursor
问题描述
i have a picturebox that contain an image (1280 X 720), i want to create a second picturebox that contain a zoomed version of the image centered around the cursor (for example a 40 X 40 square around the cursor zomed to be in a 120 X 120 square picturebox) that follow the cursor in real time in real time (if it's possible also to have a cross in the middle of the picturebox that show the precise placing of the cursor is even better).
private void Button1_Click(object sender, EventArgs e)
{
openFileDialog1.Filter = "All jpg files (*.jpg)|*.jpg";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
Bitmap img = new Bitmap(openFileDialog1.FileName);
double imageHeight = img.Height;
double imageWidth = img.Width;
pictureBox1.Image = img;
}
}
private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
{
int xupleft = e.X - 20;
int yupleft = e.Y - 20;
Rectangle myrectangle = new Rectangle(xupleft, yupleft, 40, 40);
pictureBox2.Image = pictureBox1.Image;
}
解决方案
Here is a simple example with the layout I described in the comment:
- Both PictureBoxes are nested in Panels.
- The first one is in
Zoom
mode and upon loading a file its size is adapted to avoid blank stripes to the sides. Its parent panel is used to reset to the maximum allowed size. - The 2nd one is in
AutoSize
mode and its parent panel is used to 1) hide the outer portions and 2) to calculate the offset to center the image.
Here is the simple Paint
event for pbox1:
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Size sz = pictureBox1.ClientSize;
Point pt = pictureBox1.PointToClient(Control.MousePosition);
e.Graphics.DrawLine(Pens.OrangeRed, pt.X, 0, pt.X, sz.Height);
e.Graphics.DrawLine(Pens.OrangeRed, 0, pt.Y, sz.Width, pt.Y);
}
Here is the MouseMove
the triggers the Paint
and moves pbox2:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
pictureBox1.Invalidate();
float f = 1f * pictureBox2.ClientSize.Width / pictureBox1.ClientSize.Width;
Size s2 = pictureBox2.Parent.ClientSize;
Point p2 = Point.Round(new PointF(s2.Width/2 - e.X * f , s2.Height/2 - e.Y * f ));
pictureBox2.Location = p2;
}
The file loading is a bit tricky, as it needs to analyze the aspect ratios of image and pbox:
void loadFile(string fileName)
{
if (File.Exists(fileName))
{
pictureBox1.Size = panel1.ClientSize;
pictureBox1.Location = Point.Empty;
pictureBox1.Image = Image.FromFile(fileName);
pictureBox2.Image = Image.FromFile(fileName);
pictureBox2.Location = Point.Empty;
}
Size csz = pictureBox1.ClientSize;
Size isz = pictureBox1.Image.Size;
float iar = 1f * isz.Width / isz.Height; // aspect..
float car = 1f * csz.Width / csz.Height; //..ratios
if (iar < car)
{
pictureBox1.ClientSize = new Size((int)(pictureBox1.ClientSize.Height * iar),
pictureBox1.ClientSize.Height);
}
else if (iar > car)
{
pictureBox1.ClientSize = new Size((pictureBox1.ClientSize.Width,
(int)(pictureBox1.ClientSize.Width / iar));
}
}
Note that before loading the new images one should Dispose
of the previous images! Also that after setting the pbox2.SizeMode
to Autosize
one could set it to Zoom
and scale its Size
up or down to zoom in or out, if one keeps the aspect ratio the same.
Result:
推荐阅读
- vue.js - 如何一次性启动 Cypress 测试、Vue 前端和后端?
- oracle - Oracle - 如何每年/每月/每周重复查询
- python - 计算按股息调整的百分比变化
- php - (Doctrine ORM) 如何通过多对一关系对 SELECT 进行排序
- android - 在 Android 模拟器中使用 Flutter 运行示例应用程序
- swift - 将 UiTabBar 转为 UiTabBar
- python - Thrift Hbase Python -> thrift.transport.TTransport.TTransportException: TSocket read 0 bytes
- python - 使用 if 和 for 循环比较两个列表中的多个项目
- php - 数组没有合并在一起
- sql - SQL - 当行条目是动态的时,拉取上一个日期的条目