C#笔记 picturebox功能实现(滚动放大,拖动)
1. picturebox上的坐标与原图中坐标的转换
(1) 由于图片的长宽比例和picturebox的长宽比例不同,所以图片不想拉伸的话,左右或者上下会有留白。将picturebox的sizemode设为zoom,计算留白距离。
默认情况下,在 Normal 模式中,Image 置于 PictureBox 的左上角,凡是因过大而不适合 PictureBox 的任何图像部分都将被剪裁掉。
PictureBoxSizeMode.StretchImage:使用 StretchImage 值会使图像拉伸或收缩,以便适合 PictureBox。
PictureBoxSizeMode.AutoSize:使用 AutoSize 值会使控件调整大小,以便总是适合图像的大小。
PictureBoxSizeMode.CenterImage:使用 CenterImage 值会使图像居于工作区的中心。
PictureBoxSizeMode.Zoom:使用 Zoom 的值可以使图像被拉伸或收缩以适应 PictureBox;但是仍然保持原始纵横比。
(2)picturebox的坐标都要先减去留白距离,根据比例缩放后再加上显示区域的偏移量
private OpenCvSharp.Point GetImagePoint(System.Drawing.Point p)
{
OpenCvSharp.Point imagePoint;
int width = showImage.Width;
int height = showImage.Height;
int w = Width; int h = Height;
double ratio;
if (w_empty>0)
{
ratio = h * 1.0 / height; if (p.X < w_empty || p.X > w - w_empty)
imagePoint.X = -1;
else
imagePoint.X = LUCol + (int)((p.X - w_empty) * 1.0 / ratio);
imagePoint.Y = LURow + (int)(p.Y * 1.0 / ratio);
}
else
{
ratio = w * 1.0 / width; imagePoint.X = LUCol + (int)(p.X * 1.0 / ratio);
if (p.Y < h_empty || p.Y > h - h_empty)
imagePoint.Y = -1;
else
imagePoint.Y = LURow + (int)((p.Y - h_empty) * 1.0 / ratio);
}
return imagePoint;
}
2. 滚动放大
滚动放大时,当前坐标为放大中心。
滚动放大后,显示部分占原图的比例会减小,显示部分左上角点在原图的坐标也会移动。
从原图上裁出显示部分 new Rect(LUCol, LURow, RealWidth, RealHeight)
public void pictureBox_MouseWheel(object sender, MouseEventArgs e)
{
if (Image == null) return;
if (e.Delta > 0)
{
RealWidth /= 2;
RealHeight /= 2;
LUCol = CurrentPoint.X - (int)RealWidth / 2;
LURow = CurrentPoint.Y - (int)RealHeight / 2;
}
else
{
RealWidth *= 2;
RealHeight *= 2;
LUCol = CurrentPoint.X - (int)RealWidth / 2;
LURow = CurrentPoint.Y - (int)RealHeight / 2; } judgeBounds();
showImage = new Mat(srcImage, new Rect(LUCol, LURow, RealWidth, RealHeight)); }
3. 拖动图片
public void pictureBox_MouseMove(object sender, MouseEventArgs e)
{
... if (e.Button == MouseButtons.Left)
{
EndPoint = GetImagePoint(e.Location);
int offsetX = EndPoint.X - CurrentPoint.X;
int offsetY = EndPoint.Y - CurrentPoint.Y;
LURow -= offsetY;
LUCol -= offsetX;
judgeBounds();
showImage = new Mat(srcImage, new Rect(LUCol, LURow, RealWidth, RealHeight)); }
...
}
4. 图片放大后呈现像素块
重写paint,将插值方法改为最近邻插值
public void pictureBox_Paint(object sender, PaintEventArgs e)
{
if (Image == null)
return;
var state = e.Graphics.Save();
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
e.Graphics.Clear(BackColor);
if(h_empty!=0)
e.Graphics.DrawImage(Image, 0, h_empty, Width, Height-2*h_empty);
else
e.Graphics.DrawImage(Image, w_empty, 0, Width - 2*w_empty, Height);
e.Graphics.Restore(state);
}
C#笔记 picturebox功能实现(滚动放大,拖动)的更多相关文章
- WM_SYSCOMMAND包括很多功能,比如:拖动左边框、拖动标题栏、滚动条滚动、点击最小化、双击标题栏——Delphi 通过事件代替了大部分常用的消息,所以Delphi 简单、易用、高效
procedure TForm1.WMSysCommand(var Message: TWMSysCommand); var str: string; begin case Message.CmdTy ...
- Unity 3D还原Scene场景、市面多数游戏视角高度自定义、第三人称视角分离功能:平移、拖动、看向中心等
Unity视角的高度自定义 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享. ...
- jQuery点击图片放大拖动查看效果
效果如图: 放大前: 放大后(可拖动图片浏览): 源码如下: <html xmlns="http://www.w3.org/1999/xhtml"> <head& ...
- IOS开发学习笔记036-UIScrollView-循环自动滚动
实现scrollView的自动循环滚动,需要实现几个方法. 其中scrollView中始终保存三张图片,其他的图片在滚动到时再进行加载. 循环的实现主要是在setUpdate 中,如果索引为0是第一个 ...
- 鼠标滚轮滚动慢/拖动Office出现滞后问题处理
一.说明 我对外设一直不是很了解,买的鼠标今天到了,使用时遇到了两个问题在这里记一下. 二.滚轮滚动慢处理 问题描述:在网页中滚动滚轮每次只能上下移动一点点,感觉很难受. 问题原因:此问题是滚轮滚动一 ...
- ThreeJs 导入外部三维模型,并实现鼠标滚动放大缩小旋转效果
let i = ; function init() { // create a scene, that will hold all our elements such as objects, came ...
- Verilog学习笔记简单功能实现(八)...............同步FIFO
Part 1,功能定义: 用16*8 RAM实现一个同步先进先出(FIFO)队列设计.由写使能端控制该数据流的写入FIFO,并由读使能控制FIFO中数据的读出.写入和读出的操作(高电平有效)由时钟的上 ...
- Verilog学习笔记简单功能实现(五)...............序列检测设计
这里采用夏宇闻教授第十五章的序列检测为例来学习; 从以上的状态转换图可以写出状态机的程序: module seqdet(x,out,clk,rst); input x,clk,rst; output ...
- WPF之拖动项滚动条自滚动(当拖动项到达高度的边界时候滚动条自己可以上下滚动)
参考 http://www.cnblogs.com/ListenFly/p/3281997.html Point svPoint = e.GetPosition(sv); if (sv.ActualH ...
- JavaScript学习笔记——简单无缝循环滚动展示图片的实现
今天做了一个简单的无缝循环滚动的实例,这种实例在网页中其实还挺常见的,下面分享一下我的学习收获. 首先,无缝滚动的第一个重点就是——动.关于怎么让页面的元素节点动起来,这就得学明白关于JavaScri ...
随机推荐
- 重新整理.net core 计1400篇[七] (.net core 中的依赖注入)
前言 请阅读第六篇,对于理解.net core 中的依赖注入很关键. 和我们上一篇不同的是,.net core服务注入保存在IServiceCollection 中,而将集合创建的依赖注入容器体现为I ...
- 什么是ip协议二
前言 续前面一章. 正文 看下ip选项: 看一张图: 这个ip选项一般我们不用看,即使你去搞硬件,那么做c++或者c的人会告诉你填啥,按照他们设置即可. 那么ip是如何传输的呢? 先看这张图,这张图的 ...
- argparse命令行参数的使用
import argparse def main(): #设置一些参数 parser = argparse.ArgumentParser() parser.add_argument('--device ...
- 【Oracle】Oracle数据库,第N大数据取值
Oracle数据库,第N大数据取值 没想到力扣还有数据库的练习,正好本菜鸡跑过来练手 要显示第二大的数据可以使用order by进行排序,然后用limit对显示的数据进行限制,limit1,1,以此来 ...
- -source 1.5 中不支持 diamond 运算符(中文版idea)
-source 1.5 中不支持 diamond 运算符(中文版idea) 将idea中的各个部分的jdk设为8即可,中文版的如下 1.文件-设置 2.项目上右击-打开模块设置 模块中每一个都要确认是 ...
- 浅谈DDD中的聚合
简介: 在我看来并不是MVC的基础上增加领域层,使用充血模型,解耦基础服务,我的代码就符合DDD了. 作者 | 李宇飞(菜尊)来源 | 阿里开发者公众号 在我看来并不是MVC的基础上增加领域层,使用充 ...
- [GPT] nodejs 什么情况下可以使用 import 来引入 export 的模块
在 Node.js 中,原生并不支持 ES6 的 import 语句来引入模块. 不过从 Node.js v12 开始,通过实验性功能(--experimental-modules)可以使用 .mjs ...
- dotnet C# 如果在构造函数抛出异常 析构函数是否会执行
假设在某个类型的构造函数里面抛出了异常,那么这个对象的析构函数是否会执行 如下面代码 private void F1() { try { _ = new Foo(); } catch { // 忽略 ...
- 通过Ingress-nginx实现灰度发布---灰度发布(22)
1.通过Ingress-nginx实现灰度发布 场景一: 将新版本灰度给部分用户 假设线上运行了一套对外提供 7 层服务的 Service A 服务,后来开发了个新版本 Service A' 想 要上 ...
- C++ 异常处理机制详解:轻松掌握异常处理技巧
C++ 异常处理 C++ 异常处理机制允许程序在运行时处理错误或意外情况.它提供了捕获和处理错误的一种结构化方式,使程序更加健壮和可靠. 异常处理的基本概念: 异常: 程序在运行时发生的错误或意外情况 ...