【C#】C# Winform 相册功能,图片缩放,拖拽,预览图分页
CrazyPanda发表于:2024-02-02 22:48:51浏览:313次
一、前言
在一些项目中也会用到预览图片的功能,至于为什么有一个添加图片的按钮,是因为有些项目,比如视觉相关的项目,摄像头拍摄图片,然后显示在界面上,拍一次显示一张。另一个,就是分页功能,当预览图位置不够用时就会用到。
当前软件的功能
1.添加图片
如果8个预览图都满了,会自动分页,就可以点击上一页,或者下一页了。
2.点击预览图显示大图
点击预览图,之前的拖拽和放大会自动复位
3.大图可以拖拽,放大,缩小
如果图片比较小,有这个功能就看到图片的更多细节了。
4.图片倒序排列
最后拍摄的图片,始终显示在前面,方便用户更好的观察到最新的图片
二、实现功能
新建一个winform项目,界面如下:
界面中大图和预览图都是 PictureBox 控件 ,至于控件的名字,在下面的代码中可以看到,在文章的最后面,我会附上这个Demo源码,Visual Studio 版本为2019.
代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace 相册功能 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //本地的相册列表 private string AlbumPath = Application.StartupPath + "\\Album"; //相册列表 private List<PictureBox> PictureBoxList = new List<PictureBox>(); //图片路径列表 private List<string> FilesinfoList = new List<string>(); //相册显示的图片列表 private List<Bitmap> BitmapList = new List<Bitmap>(); //pictureBox1的初始位置 private Point PicStartPos; //pictureBox1的初始大小 private Size PicSize; //测试用 int index = -1; //当前页数 private int NowPage = 1; //总页数 private int TotalPage = 1; //鼠标滚轮缩放图片的增量值 private int ZoomStep = 20; //鼠标是否在拖拽中 private bool IsMove = false; //鼠标点击的位置 private Point MouseDownPoint; private void Form1_Load(object sender, EventArgs e) { PicStartPos = pictureBox1.Location; PicSize = pictureBox1.Size; this.pictureBox1.MouseWheel += new MouseEventHandler(this.pictureBox1_MouseWheel); PictureBoxList.Add(PictureBox_ImgList1); PictureBoxList.Add(PictureBox_ImgList2); PictureBoxList.Add(PictureBox_ImgList3); PictureBoxList.Add(PictureBox_ImgList4); PictureBoxList.Add(PictureBox_ImgList5); PictureBoxList.Add(PictureBox_ImgList6); PictureBoxList.Add(PictureBox_ImgList7); PictureBoxList.Add(PictureBox_ImgList8); //添加图片的点击事件 for (int i = 0; i < PictureBoxList.Count; i++) { PictureBoxList[i].Click += new System.EventHandler(PictureBoxClick); } DirectoryInfo directory = new DirectoryInfo(AlbumPath); FileSystemInfo[] filesArray = directory.GetFileSystemInfos(); foreach (var item in filesArray) { if (item.Attributes != FileAttributes.Directory) { FilesinfoList.Add(item.FullName); } } } /// <summary> /// 上一页 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button_Back_Click(object sender, EventArgs e) { if (NowPage <= 1) return; NowPage--; for (int i = 0; i < PictureBoxList.Count; i++) { PictureBoxList[i].Image = null; } List<Bitmap> list = GetPagesBitmap(NowPage); for (int i = 0; i < list.Count; i++) { PictureBoxList[i].Image = list[i]; } pictureBox1.Image = list[0]; //设置坐标 pictureBox1.Location = PicStartPos; //设置控件宽高 pictureBox1.Size = PicSize; Label_NumberOfPages.Text = string.Format("{0} / {1}", NowPage, TotalPage); BackNextButtonType(); } /// <summary> /// 下一页 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button_Next_Click(object sender, EventArgs e) { if (NowPage >= TotalPage) return; NowPage++; for (int i = 0; i < PictureBoxList.Count; i++) { PictureBoxList[i].Image = null; } List<Bitmap> list = GetPagesBitmap(NowPage); for (int i = 0; i < list.Count; i++) { PictureBoxList[i].Image = list[i]; } pictureBox1.Image = list[0]; //设置坐标 pictureBox1.Location = PicStartPos; //设置控件宽高 pictureBox1.Size = PicSize; Label_NumberOfPages.Text = string.Format("{0} / {1}", NowPage, TotalPage); BackNextButtonType(); } /// <summary> /// 添加图片 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Button_Add_Click(object sender, EventArgs e) { index++; AddPicture(new Bitmap(FilesinfoList[index])); if (index >= FilesinfoList.Count - 1) index = -1; } /// <summary> /// 添加图片 /// </summary> /// <param name="bitmap"></param> private void AddPicture(Bitmap bitmap) { if (bitmap == null) return; //添加到图片列表 BitmapList.Add(bitmap); //界面预留图中显示 pictureBox1.Image = bitmap; //设置坐标 pictureBox1.Location = PicStartPos; //设置控件宽高 pictureBox1.Size = PicSize; //计算当前总页数 int page = BitmapList.Count / PictureBoxList.Count; int remainder = BitmapList.Count % PictureBoxList.Count; TotalPage = remainder > 0 ? page + 1 : page; Label_NumberOfPages.Text = string.Format("{0} / {1}", NowPage, TotalPage); BackNextButtonType(); //让图片按逆向顺序显示 List<Bitmap> reverseSort = new List<Bitmap>(); for (int i = BitmapList.Count - 1; i >= 0; i--) { reverseSort.Add(BitmapList[i]); } for (int i = 0; i < reverseSort.Count; i++) { if (i <= 7) PictureBoxList[i].Image = reverseSort[i]; } } /// <summary> /// 8张预览图片的点击事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void PictureBoxClick(Object sender, System.EventArgs e) { PictureBox pictureBox = (PictureBox)sender; if (pictureBox != null && pictureBox.Image != null) { pictureBox1.Image = pictureBox.Image; //设置坐标 pictureBox1.Location = PicStartPos; } } /// <summary> /// 获取索引对应的图片 /// </summary> /// <param name="index"></param> /// <returns></returns> private List<Bitmap> GetPagesBitmap(int index) { if (BitmapList.Count <= 0) return null; //页数 int page = BitmapList.Count / PictureBoxList.Count; //余数 int remainder = BitmapList.Count % PictureBoxList.Count; //总页数 int allPage = remainder > 0 ? page + 1 : page; if (index > allPage) return null; //索引起点 int start = (index * PictureBoxList.Count) - PictureBoxList.Count; //索引结束点 int end = (index * PictureBoxList.Count) - 1; if (end > BitmapList.Count) end = BitmapList.Count - 1; List<Bitmap> reverseSort = new List<Bitmap>(); for (int i = BitmapList.Count - 1; i >= 0; i--) { reverseSort.Add(BitmapList[i]); } List<Bitmap> list = new List<Bitmap>(); for (int i = start; i <= end; i++) { list.Add(reverseSort[i]); } if (list.Count > 0) return list; return null; } /// <summary> /// 上一页,下一页按钮状态 /// </summary> private void BackNextButtonType() { Button_Next.Enabled = true; Button_Back.Enabled = true; //现在页 = 总页数 if (NowPage == TotalPage) Button_Next.Enabled = false; //现在页 小于等于 1 if (NowPage <= 1) Button_Back.Enabled = false; } private void pictureBox1_MouseDown(object sender, MouseEventArgs e) { if (pictureBox1.Image == null) return; if (e.Button == MouseButtons.Left) { MouseDownPoint.X = Cursor.Position.X; //记录鼠标左键按下时位置 MouseDownPoint.Y = Cursor.Position.Y; IsMove = true; pictureBox1.Focus(); //鼠标滚轮事件(缩放时)需要picturebox有焦点 } } private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { IsMove = false; } } private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (pictureBox1.Image == null) return; pictureBox1.Focus(); //鼠标在picturebox上时才有焦点,此时可以缩放 if (IsMove) { int x, y; //新的pictureBox1.Location(x,y) int moveX, moveY; //X方向,Y方向移动大小。 moveX = Cursor.Position.X - MouseDownPoint.X; moveY = Cursor.Position.Y - MouseDownPoint.Y; x = pictureBox1.Location.X + moveX; y = pictureBox1.Location.Y + moveY; pictureBox1.Location = new Point(x, y); MouseDownPoint.X = Cursor.Position.X; MouseDownPoint.Y = Cursor.Position.Y; } } private void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { if (pictureBox1.Image == null) return; PictureBox pbox = pictureBox1; int x = e.Location.X; int y = e.Location.Y; int ow = pbox.Width; int oh = pbox.Height; int VX, VY; //因缩放产生的位移矢量 if (e.Delta > 0) //放大 { //第1步 pbox.Width += ZoomStep; pbox.Height += ZoomStep; //第2步 PropertyInfo pInfo = pbox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); Rectangle rect = (Rectangle)pInfo.GetValue(pbox, null); //第3步 pbox.Width = rect.Width; pbox.Height = rect.Height; //Console.WriteLine(string.Format("宽:{0},高:{1}",pbox.Width,pbox.Height)); } if (e.Delta < 0) //缩小 { //防止一直缩成负值 if (pbox.Width < 300) return; pbox.Width -= ZoomStep; pbox.Height -= ZoomStep; PropertyInfo pInfo = pbox.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic); Rectangle rect = (Rectangle)pInfo.GetValue(pbox, null); pbox.Width = rect.Width; pbox.Height = rect.Height; } //第4步,求因缩放产生的位移,进行补偿,实现锚点缩放的效果 VX = (int)((double)x * (ow - pbox.Width) / ow); VY = (int)((double)y * (oh - pbox.Height) / oh); pbox.Location = new Point(pbox.Location.X + VX, pbox.Location.Y + VY); } } }
代码中,鼠标缩放,拖拽功能,需要在控件里选择对应的方法,否则运行就没有效果
运行后,效果就如文章开头的 Gif 图片
源码:点击下载
结束
如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢
end
猜你喜欢
- 【C#】C# Winform 日志系统
- 目录一、效果1.刷新日志效果2.单独日志的分类3.保存日志的样式二、概述三、日志系统API1.字段Debug.IsScrollingDebug.VersionDebug.LogMaxLenDebug.LogTitleDebug.IsConsoleShowLog2.方法Debug.Log(string)Debug.Log(string, params object[])Debug.Logs(string)Debug.Logs(string, params object[])Debug.LogSav
- 【C#】从零开始用C#写一个桌面应用程序(一)基础操作
- 准备winform应用程序编写桌面应用客户端的技术。xaml一种标记语言。winform程序组成。 程序入口: form.cs和它的设计文件: 启动的过程以及涉及的文件:main函数: form1的构造函数和它的设计文件: main-》构造form-》initializeComponent-》 拖入一个 button控件可以看到: 这时我们已经梳理启动过程。使用组件的方法 可以在
- 【C#】C# Winfrom 右键菜单
- 目录一、概述二、新建 winform 项目三、给图片控件添加右键菜单四、给菜单添加点击事件五、测试结束一、概述ContextMenuStrip 是 Windows 窗体应用程序中的一个控件,它提供了一个弹出菜单,用于在用户右键单击控件或其他界面元素时显示上下文相关的选项。它通常用于在图形用户界面中提供快捷操作和功能。ContextMenuStrip 控件可以通过在 Visual Studio 的设计器中拖放方式添加到窗体上,或者通过编程方式创建和配置。它可以与其他控件(如按钮、文本框等
- 【C#】C#调用win10系统自带软键盘的方法
- 上次做了个笔记是关于调用windows系统自带的触摸键盘的方法:C#调用Windows系统自带触摸键盘的方法_c# 虚拟键盘-CSDN博客除了调用触摸键盘,我们也可以通过调用win10的自带软键盘作为输入途径。方法很简单。1、添加using System.Diagnostics引用。2、创建进程Process Winvirkey = Process.Start("osk.exe");3、打开键盘:Winvirkey = Process.Start("osk.exe&
- 【C#】C# Winfrom 常用功能整合-1
- 目录Winform 最大化遮挡任务栏和全屏显示问题Winfrom 给图片画 矩形,椭圆形,文字Winfrom TabControl选项卡 动态添加,删除,修改Winform ErrorProvider控件Winform 读取Resources图片Winfrom 读取内存条占用大小,硬盘占用大小Winform 全局捕获异常Winform 用线程写入TXT文件,并更新UI和进度Winform 摄像头识别二维码,保存图片Winform 判断窗体是否已打开Winform 动态添加菜单列表,点击切换对应面
- 【C#】c#开发桌面应用程序用什么框架
- style="text-wrap: wrap;">在C#开发桌面应用程序时,可以使用以下几种常见的框架:</p><ol class=" list-paddingleft-2" style="width: 1529.1px; text-wrap: wrap;"><li><p>Windows Forms:这是一种由.NET Framework提供的GUI框架,它提供了丰富的GUI控件和易于使用的编程模型。Windows Forms在C#开发领域中使用非常广泛,并且已经存在多年,获得了广泛的支持和优化。</p></li></ol
- 【C#】C# Winform 多个程序之间的通信(非Scoket)
- 效果功能:打开窗体自动连接主程序,并自动添加到列表,可以向子程序群发消息可以向单个程序单独发送消息在退出程序后,添加的程序列表会自动移除一、概述参考:C# Winfrom程序之间通讯_c# sendmessege copydatastruct 返回多个值_熊思宇的博客-CSDN博客在之前我写过 winform 程序与程序之间的通信,但是这个版本有个问题,那就是只能由两个程序进行通信,同时打开多个程序的话,接收方收到的数据就会一模一样,这次发表这个教程,也就是要解决这个问题。归根结底,还是&nbs
- 【C#】C# Winform 相册功能,图片缩放,拖拽,预览图分页
- 一、前言在一些项目中也会用到预览图片的功能,至于为什么有一个添加图片的按钮,是因为有些项目,比如视觉相关的项目,摄像头拍摄图片,然后显示在界面上,拍一次显示一张。另一个,就是分页功能,当预览图位置不够用时就会用到。当前软件的功能1.添加图片如果8个预览图都满了,会自动分页,就可以点击上一页,或者下一页了。2.点击预览图显示大图点击预览图,之前的拖拽和放大会自动复位3.大图可以拖拽,放大,缩小如果图片比较小,有这个功能就看到图片的更多细节了。4.图片倒序排列最后拍摄的图片,始终显示在前面,方便用户
栏目分类全部>
推荐文章
- 【C#】C# Winfrom 常用功能整合-1
- 【UniApp】最新使用uniapp本地打包APP安卓,已排坑
- 【Python】Python中使用len函数的用法和常见应用场景
- 【Python】利用Python和WebDriver扩展自动化处理网页的滑动验证码
- 【Vue】Antd Pro Vue的使用(五)—— 多文件上传回显问题
- 【UniApp】如何在uniapp中实现全局状态管理
- 【PHP】php单例模式的应用场景有哪些
- 【Go】Golang标准库介绍(三)
- 【UniApp】如何在uniapp中实现倒计时和闹钟功能
- 【Elasticsearch】linux安装Elasticsearch及ik分词器