基于C#一个制作图像的特写窗口

 更新时间:2025年01月15日 16:09:38   作者:坐井观老天  
许多网站都会显示一个特写窗口,其中显示放大的图像部分,以便您可以看到更多细节,本文将使用C#制作一个简单的图像的特写窗口,感兴趣的可以了解下

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

特写图实际上只是原始图像的全尺寸副本。(“主”图像是较小比例的相同图像。)要显示特写图,程序会在名为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);
}

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

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

到此这篇关于基于C#一个制作图像的特写窗口的文章就介绍到这了,更多相关C#图像特写窗口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#多线程等待所有子线程结束的示例

    C#多线程等待所有子线程结束的示例

    这篇文章主要介绍了C#多线程等待所有子线程结束的示例,帮助大家更好的理解和学习c#编程语言,感兴趣的朋友可以了解下
    2020-12-12
  • C# 泛型集合类List<T>使用总结

    C# 泛型集合类List<T>使用总结

    本文主要主要介绍了C# 泛型集合类List<T>使用总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧<BR>
    2022-05-05
  • C#利用FileSystemWatcher实时监控文件的增加,修改,重命名和删除

    C#利用FileSystemWatcher实时监控文件的增加,修改,重命名和删除

    好多时候,我们都需要知道某些目录下的文件什么时候被修改、删除过等。本文将利用FileSystemWatcher实现实时监控文件的增加,修改,重命名和删除,感兴趣的可以了解一下
    2022-08-08
  • C#实现跨线程操作控件方法

    C#实现跨线程操作控件方法

    这篇文章主要介绍了C#实现跨线程操作控件方法,主要采用异步访问方式实现,需要的朋友可以参考下
    2014-10-10
  • 在C# WebAPI中实现多版本控制的方法

    在C# WebAPI中实现多版本控制的方法

    随着应用程序的不断演化和功能的不断扩展,API 版本控制成为了开发和维护 WebAPI 时不可或缺的一部分,在本文中,我们将介绍如何在现代 C# WebAPI 项目中有效地实施 API 版本控制,并分享一些最佳实践,需要的朋友可以参考下
    2025-11-11
  • c++ 中的关键字 const含义详解

    c++ 中的关键字 const含义详解

    C++ 中的 const 关键字是一个强大的工具,主要用于定义“只读”变量或对象,告诉编译器和程序员,被其修饰的内容不应被改变,本文给大家介绍c++ 中的关键字 const含义,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • C#中的yield关键字详解

    C#中的yield关键字详解

    本文详细讲解了C#中的yield关键字,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • 浅析WPF中Binding的数据校验和类型转换

    浅析WPF中Binding的数据校验和类型转换

    在WPF开发中,Binding实现了数据在Source和Target之间的传递和流通,那在WPF开发中,如何实现数据的校验和类型转换呢,下面就跟随小编一起学习一下吧
    2024-03-03
  • c# 实现发送邮件到指定邮箱

    c# 实现发送邮件到指定邮箱

    这篇文章主要介绍了c# 如何实现发送邮件到指定邮箱,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-03-03
  • C#获取文件、文件夹和驱动器的信息示例详解

    C#获取文件、文件夹和驱动器的信息示例详解

    在C#中,文件、文件夹和驱动器是文件系统操作的基本元素,了解如何获取这些元素的信息对于开发文件处理和管理工具至关重要,本文将详细介绍如何在C#中获取有关文件、文件夹和驱动器的信息,并提供相应的示例,需要的朋友可以参考下
    2024-08-08

最新评论