效果
1.图片放大,缩小,拖拽功能
2.添加图片,分页功能
在很多项目中也需要用到预览图片的功能,至于为什么加一个添加图片的功能,是因为有些项目,比如视觉相关的工作,会需要摄像机采集图片,然后显示在界面上,所以,图片也是一张一张的添加的,另外,就是分页功能,当预览图位置不够用时就会用到,所以我也加了进来。
当前软件的功能
如果8个预览图都满了,会自动分页,就可以点击上一页,或者下一页了。
点击预览图,之前的拖拽和放大会自动复位
如果图片比较小,有这个功能就看到图片的更多细节了。
最后添加的图片,始终显示在最前面,这也就在分页上和常规的有点区别了,如图
如果你用的正序排列,可以看看这个帖子:
C# 分页计算 总页数、当前页数据集合_熊思宇的博客-CSDN博客
新建一个winform项目,界面如下:
没有太复杂的界面,大图和预览图都是用的 PictureBox 控件 ,控件的名字,可以看下面的代码,在文章的最下面,我会附上这个Demo源码,有兴趣的可以下载。
- 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);
- }
-
-
- }
- }
代码中,鼠标缩放,拖拽功能,需要在控件里添加对应的事件,否则就没有效果了
运行后,效果就如文章开头所示,这个位置还是先不加图片了
源码:点击下载
如果这个帖子对你有用,欢迎 关注 + 点赞 + 留言,谢谢
end