使用 C# 制作图像的特写窗口

ops/2025/1/15 15:08:23/

许多网站都会显示一个特写窗口,其中显示放大的图像部分,以便您可以看到更多细节。您在主图像上移动鼠标,它会在单独的图片中显示特写。此示例执行的操作类似。(示例使用的一些数学运算非常棘手,因此您可能需要仔细查看才能了解其工作原理。)

特写图实际上只是原始图像的全尺寸副本。(“主”图像是较小比例的相同图像。)要显示特写图,程序会在名为picCloseup的PictureBox中显示全尺寸图像。该控件位于名为panCloseup的Panel内。通过在panCloseup内移动picCloseup,程序可以显示全尺寸图像的不同部分。

以下代码使程序准备启动。

// Save the original image.
private Bitmap OriginalImage, ShadedImage;
private int SmallWidth, SmallHeight;
private float ScaleX, ScaleY;
private void Form1_Load(object sender, EventArgs e)
{OriginalImage = picWhole.Image as Bitmap;picCloseup.Image = OriginalImage;picCloseup.SizeMode = PictureBoxSizeMode.AutoSize;// Make a shaded version of the image.ShadedImage = new Bitmap(OriginalImage);using (Graphics gr = Graphics.FromImage(ShadedImage)){using (Brush br =new SolidBrush(Color.FromArgb(128, 255, 255, 255))){Rectangle rect = new Rectangle(0, 0,ShadedImage.Width, ShadedImage.Height);gr.FillRectangle(br, rect);}}// Get scale factors to map from big scale to small scale.ScaleX = (float)panCloseup.ClientSize.Width /OriginalImage.Width;ScaleY = (float)panCloseup.ClientSize.Height /OriginalImage.Height;// See how big the closeup is on the small scale.SmallWidth = (int)(ScaleX * picWhole.ClientSize.Width);SmallHeight = (int)(ScaleY * picWhole.ClientSize.Height);
}

此代码保存原始图像并制作该图像的亮化版本。要制作亮化版本,它会复制原始图像,然后用半透明的白色矩形填充它。这将成为您将鼠标移到其上的主图像。

当鼠标移入或移出主图像时,将执行以下代码。

// Use the shaded background image.
private void picWhole_MouseEnter(object sender, EventArgs e)
{picWhole.Image = ShadedImage;panCloseup.Visible = true;
}// Use the regular image.
private void picWhole_MouseLeave(object sender, EventArgs e)
{picWhole.Image = OriginalImage;panCloseup.Visible = false;
}

当鼠标位于主图像之外时,程序显示正常的非亮化版本。当鼠标进入图像时,程序切换为显示亮化图像。

当鼠标在主图像上移动时,以下代码会显示鼠标周围区域的特写。

// Display a closeup of this area.
private Rectangle ViewingRectangle;
private void picWhole_MouseMove(object sender, MouseEventArgs e)
{// Position picCloseup inside its parent Panel.float x = (float)e.X / picWhole.ClientSize.Width *OriginalImage.Width -(float)panCloseup.ClientSize.Width / 2;float y = (float)e.Y / picWhole.ClientSize.Height *OriginalImage.Height -(float)panCloseup.ClientSize.Height / 2;if (x < 0) x = 0;if (y < 0) y = 0;if (x > OriginalImage.Width - panCloseup.ClientSize.Width)x = OriginalImage.Width - panCloseup.ClientSize.Width;if (y > OriginalImage.Height - panCloseup.ClientSize.Height)y = OriginalImage.Height - panCloseup.ClientSize.Height;picCloseup.Location = new Point(-(int)x, -(int)y);// Record the position we are viewing.ViewingRectangle = new Rectangle((int)x, (int)y,panCloseup.ClientSize.Width, panCloseup.ClientSize.Height);// Draw the closeup area.picWhole.Invalidate();
}

首先,代码决定鼠标周围的区域在哪里。如果该区域部分位于主图像之外,则代码会调整其 X 和 Y 坐标,使该区域位于主图像内。这样可以让特写显示尽可能多的图像。

代码将picCloseup移动到panCloseup内,以显示全尺寸图像的正确部分。然后,它将在变量ViewingRectangle中记录主图像上将显示的区域,并使主图像无效以使其重绘。以下代码显示了主图片的Paint事件处理程序,该处理程序处理该重绘。

// Draw the viewing area.
private void picWhole_Paint(object sender, PaintEventArgs e)
{// Scale so we can draw in the full scale coordinates.e.Graphics.ScaleTransform(ScaleX, ScaleY);// Draw the viewing area using the original image.e.Graphics.DrawImage(OriginalImage, ViewingRectangle, ViewingRectangle, GraphicsUnit.Pixel);//e.Graphics.DrawRectangle(Pens.Red, ViewingRectangle);
}

此代码使用变换,因此它可以使用全尺寸图像的坐标而不是主图像(您可能还记得,主图像是缩小比例的)的坐标进行绘制。然后,它将原始全尺寸图像的一部分复制到主图像上,以显示鼠标周围的区域。结果是主图像除了此区域外都被阴影化,此区域以原始亮度绘制。取消注释此方法中的最后一行,以在主图像的特写区域周围绘制一个红色矩形。

我承认这是一个令人困惑的例子,但它的效果非常酷,所以我鼓励你下载并尝试一下。如果你对代码进行一些实验,你就能弄清楚它是如何工作的。(土卫二是一颗特别奇怪的卫星!)


http://www.ppmy.cn/ops/150318.html

相关文章

vue运用uniapp框架开发企业微信小程序中常用的一些基础方法

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vue运用uniapp框架开发企业微信小程序中常用的一些基础方法”。 作为一名程序员&#xff0c;很多代码都是忘了再用&#xff0c;用了再忘。 今天梳理下日常开发中常用到的一些基础的方法&#xff0c;以方便后期开…

LSA更新、撤销

LSA的新旧判断&#xff1a; 1.seq&#xff0c;值越大越优先 2.chksum&#xff0c;值越大越优先 3.age&#xff0c;本地的LSA age和收到的LSA age作比较 如果差值<900s&#xff0c;认为age一致&#xff0c;保留本地的&#xff1a;我本地有一条LSA是100 你给的是400 差值小于…

基础入门-抓包技术HTTPS协议APP小程序PC应用Web证书信任转发联动

知识点&#xff1a; 1、抓包技术-Web应用-http/s-Burp&Yakit 2、抓包技术-APP应用-http/s-Burp&Yakit 3、抓包技术-PC端应用-http/s-Burp&Yakit 4、抓包技术-WX小程序-http/s-Burp&Yakit 5、抓包技术-软件联动-http/s-Proxifier 6、抓包技术-通用方案-http/s-R…

算法-盒子中小球的最大数量

原题目链接&#xff1a;1742. 盒子中小球的最大数量 - 力扣&#xff08;LeetCode&#xff09; 你在一家生产小球的玩具厂工作&#xff0c;有 n 个小球&#xff0c;编号从 lowLimit 开始&#xff0c;到 highLimit 结束&#xff08;包括 lowLimit 和 highLimit &#xff0c;即 n…

如何开放2375和2376端口供Docker daemon监听

Linux (以 Ubuntu 为例) 1. 修改 Docker 配置文件 打开 Docker 的配置文件 /etc/docker/daemon.json。如果该文件不存在&#xff0c;则可以创建一个新的。 bash sudo nano /etc/docker/daemon.json在配置文件中添加以下内容&#xff1a; json {"hosts": ["un…

C#,任意阶幻方(Magic Square)的算法与源代码

1 什么是幻方&#xff1f; 幻方&#xff08;Magic Square&#xff09;是一种将数字安排在正方形格子中&#xff0c;使每行、列和对角线上的数字和都相等的方法。 幻方也是一种中国传统游戏。旧时在官府、学堂多见。它是将从一到若干个数的自然数排成纵横各为若干个数的正方形&…

【机器学习】实战:天池工业蒸汽量项目(一)数据探索

文章目录 1、项目介绍2、导入数据探索工具包3、数据加载4、查看数据集变量信息5、查看数据统计信息6、查看数据字段信息7、箱式图数据探索8、查看数据分布9、特征相关性10、特征筛选 个人主页&#xff1a;道友老李 欢迎加入社区&#xff1a;道友老李的学习社区 【机器学习】实…

linux自动分区后devmappercentos-home删除后合并到其它分区上

删除其他分区&#xff0c;合并到对应分区上增加磁盘空间 删除开机默认挂载 /dev/mapper/centos-home vim /etc/fstab 把 /dev/mapper/centos-home 这一行删除掉命令行取消挂载 /dev/mapper/centos-home umount /dev/mapper/centos-home删除掉逻辑卷 home lvsdf -hlvremove /…