当前位置:首页 > 人生 > 作品墙 > 正文内容

图片框PictureBox 控件调用文档

作品墙1周前 (10-23)


命名空间:CConUI
继承:System.Windows.Forms.Control
定位:自绘图片框,支持边框、BackColor 背景色、多种图片显示模式(含 ARGB 边框色)、鼠标拖动 + 滚轮缩放、右键复位、蚂蚁线(AntLine)子控件联动,以及多种图像区域提取 / 定位方法。

依赖:CConPlus.Enum.ImageSizeMode、CConPlus.GraphicsC.DrawImageInRect、CConPlus.Rect.MoveRectangleInward、ArgbColorEditor(本程序集)、AntLine(本程序集)。


一、快速上手

using CConUI;

// 1. 创建控件并放到容器
PictureBox pb = new PictureBox();
pb.Parent = this;
pb.Dock = DockStyle.Fill;

// 2. 设置图片与显示模式
pb.Image = Image.FromFile("test.png");
pb.ImageSizeMode = CConPlus.Enum.ImageSizeMode.Zoom;   // 等比缩放适应

// 3. 边框与背景
pb.BorderSize = 6;
pb.BorderColor = Color.FromArgb(255, 110, 120, 130);
pb.BackColor = Color.FromArgb(255, 50, 50, 50);

// 4. 开启鼠标拖动 + 滚轮缩放 + 右键复位
pb.MouseEnabled = true;
pb.RightRestore = true;

// 5. 监听图片变化事件
pb.Change += (s, e) =>
{
    Console.WriteLine("图片已更换");
};

二、构造函数

public PictureBox()

项目说明
参数无
作用创建图片框控件
默认尺寸150 × 150 像素
默认背景色Color.FromArgb(50, 50, 50)
默认边框大小6 像素
默认边框颜色Color.FromArgb(110, 120, 130)
默认图片显示模式CConPlus.Enum.ImageSizeMode.None
默认鼠标功能MouseEnabled = false
默认右键复位RightRestore = true
内嵌子控件自动创建并添加一个 AntLine(Dock = Fill、Visible = false、初始 AntRect = (20,20,100,100))
绘制样式UserPaint | AllPaintingInWmPaint | OptimizedDoubleBuffer | Selectable(可接收滚轮消息)
TabStoptrue
var pb = new PictureBox
{
    Size = new Size(400, 300),
    Dock = DockStyle.Fill
};
panel1.Controls.Add(pb);

三、公开事件

public event EventHandler Change

项目说明
参数EventHandler:sender 为当前 PictureBox,e 为 EventArgs.Empty
触发时机Image 属性被赋值时(包括赋相同值也会触发,因为 setter 中无“值相同”判断)
触发顺序先 Invalidate()(重绘),再触发 Change
用途监听图片被替换的事件;例如重置缩放、更新外部状态
pb.Change += (s, e) =>
{
    // 图片变化后自动复位缩放/平移
    pb.Redraw();
};

设计器属性窗口 Category 名为 Ccon(注意小写 c)。


四、公开属性

4.1 public CConPlus.Enum.ImageSizeMode ImageSizeMode

项目说明
类型CConPlus.Enum.ImageSizeMode
默认CConPlus.Enum.ImageSizeMode.None
CategoryCCon_图片
作用图片在边框内侧区域的显示方式;由 CConPlus.GraphicsC.DrawImageInRect 解释,本控件的 CalcImageRectInInner 也按以下三种主要语义处理:
Stretch:拉伸铺满;Zoom:等比缩放适应;其他(None / Center):原始尺寸居中
副作用赋值后立即 Invalidate() 重绘
pb.ImageSizeMode = CConPlus.Enum.ImageSizeMode.Zoom;

4.2 public System.Drawing.Image Image

项目说明
类型System.Drawing.Image
默认null
CategoryCCon_图片
作用要显示的图片。null 时不绘制图片(只画边框和背景)
副作用赋值后:① Invalidate() 重绘;② 触发 Change 事件
备注控件**不负责** Dispose 传入的 Image;图片资源由调用方管理
pb.Image = Image.FromFile("photo.jpg");
// ...
// 不再使用时可自行释放原图
var old = pb.Image;
pb.Image = null;
if (old != null) old.Dispose();

4.3 public int BorderSize

项目说明
类型int
默认6
CategoryCCon_边框
作用边框宽度(像素)。为 0 时不绘制边框,图片绘制区域铺满整个客户区
备注**未做上下限校验**,请自行保证非负;负数会导致 Pen 构造异常或图片区域异常
pb.BorderSize = 4;

4.4 public Color BorderColor

项目说明
类型Color
默认Color.FromArgb(110, 120, 130)
CategoryCCon_边框
作用边框颜色,支持 ARGB 透明度
编辑器ArgbColorEditor:属性面板中显示为色块,点击弹出色板可编辑 Alpha
pb.BorderColor = Color.FromArgb(200, 0, 120, 215);

4.5 public override Color BackColor

项目说明
类型Color(重写 Control.BackColor)
默认Color.FromArgb(50, 50, 50)
CategoryCCon_颜色
作用控件背景填充色;在 OnPaintBackground 中用该颜色铺满 ClientRectangle
备注未使用 ARGB 编辑器(跟随普通 ColorEditor),如需透明背景请使用代码设置 Color.FromArgb(...)
pb.BackColor = Color.Black;

4.6 public bool MouseEnabled

项目说明
类型bool
默认false
CategoryCCon_控制
作用是否启用鼠标功能:
① 左键按住拖动 → 平移图片;
② 滚轮 → 以鼠标位置为中心缩放图片(0.1× ~ 100×);
③ 右键 → 复位到初始显示(由 RightRestore 控制)
副作用设为 false 时会立即结束拖动、光标恢复为 Cursors.Default 并重绘
pb.MouseEnabled = true;

4.7 public bool RightRestore

项目说明
类型bool
默认true
CategoryCCon_控制
作用开启鼠标功能时,右键松开是否复位(调用 Redraw())
备注**仅在 MouseEnabled = true 时有效**
pb.MouseEnabled = true;
pb.RightRestore = true;  // 右键复位

4.8 public AntLine AntLine

项目说明
类型CConUI.AntLine(本程序集的蚂蚁线控件)
默认非 null;构造函数中已创建并添加
作用获取/替换图片框上叠加的蚂蚁线子控件;可用于设置选框矩形、联动裁剪区域
setter 行为把传入的 AntLine 设置为子控件(Controls.Add(value));
**注意**:不会自动从 Controls 移除旧的 AntLine,多次赋值可能导致多个 AntLine 叠加
备注默认 Visible = false;需要显示时自行 pb.AntLine.Visible = true;
// 显示蚂蚁线
pb.AntLine.Visible = true;
pb.AntLine.AntRect = new Rectangle(50, 50, 200, 150);

// 隐藏蚂蚁线
pb.AntLine.Visible = false;

// 用蚂蚁线选框获取该区域的图片内容
Bitmap crop = pb.GetImageInRectangle(pb.AntLine.AntRect);
if (crop != null) { /* 使用 crop ... */ crop.Dispose(); }

五、公开方法

5.1 public void Redraw()

项目说明
参数无
返回void
作用复位鼠标拖动与缩放效果,把 _zoom 恢复为 1、_offset 恢复为 (0,0)、清空拖动状态、光标恢复默认,并重绘
典型场景① 右键复位(由 OnMouseUp 内部触发);② 更换图片后主动复位;③ 提供外部“复位按钮”的功能实现
pb.MouseEnabled = true;
pb.RightRestore = true;  // 鼠标右键自动复位

// 外部按钮手动复位
btnReset.Click += (s, e) => pb.Redraw();

5.2 public Rectangle GetImageDisplayRectangle()

项目说明
参数无
返回Rectangle:图片在**控件客户区坐标系**中当前实际显示的矩形(已叠加 zoom + offset)
返回空值情况① Image == null;② 边框内侧无效(BorderSize 过大或控件尺寸过小)
作用用于获知图片当前“画在哪”,可配合蚂蚁线、命中检测等使用
Rectangle disp = pb.GetImageDisplayRectangle();
Console.WriteLine("当前图片显示区域:" + disp);

5.3 public Rectangle GetVisibleImageRectangle()

项目说明
参数无
返回Rectangle:GetImageDisplayRectangle() 与边框内侧区域的**交集**(即真正在控件内可见的部分)
返回空值情况① Image == null;② 图片完全拖出可视区域
作用计算“用户当前能看到的图片范围”,用于精确反馈(如拖动进度、裁剪显示区域)
Rectangle visible = pb.GetVisibleImageRectangle();
if (visible.IsEmpty)
    Console.WriteLine("图片已完全移出可视区域");

5.4 public Bitmap GetImageInRectangle(Rectangle rect)

参数类型说明
rectRectangle控件**客户区**坐标系下的矩形区域
返回说明
Bitmap该区域对应的原图裁剪结果。**调用方负责 Dispose()**
null① Image == null;② rect 与边框内侧无交集;③ 图像内容为空白
项目说明
作用将“用户看到的某个屏幕/控件区域”反算回原图坐标,裁剪出对应 Bitmap
核心流程① rect ∩ 边框内侧 → valid;② 反变换 valid 得到 inner 坐标系中的矩形;③ 再映射回原图像素坐标 srcRect;④ srcRect ∩ 原图边界;⑤ DrawImage 输出为 Bitmap
插值质量InterpolationMode.HighQualityBicubic + PixelOffsetMode.HighQuality
典型场景蚂蚁线框选裁剪、导出当前视口截图、屏幕取色前的像素读取
// 场景一:根据蚂蚁线选框裁剪
pb.AntLine.AntRect = new Rectangle(50, 50, 200, 150);
pb.AntLine.Visible = true;

Bitmap crop = pb.GetImageInRectangle(pb.AntLine.AntRect);
if (crop != null)
{
    crop.Save("crop.png", System.Drawing.Imaging.ImageFormat.Png);
    crop.Dispose();  // 必须由调用方释放
}

// 场景二:导出当前可视视口内的图片
Rectangle visible = pb.GetVisibleImageRectangle();
if (!visible.IsEmpty)
{
    using (Bitmap visibleBmp = pb.GetImageInRectangle(visible))
    {
        if (visibleBmp != null) visibleBmp.Save("viewport.png");
    }
}

5.5 public void ShowImageRegion(Rectangle imageRect)

参数类型说明
imageRectRectangle要聚焦显示的**原图像素坐标**区域
返回说明
void无返回值
项目说明
作用自动计算 _zoom 与 _offset,使指定的原图区域**居中**并**最大化**显示在边框内侧区域内
处理流程① imageRect ∩ 原图;② 等比缩放比 = min(innerW/imgW, innerH/imgH);③ 限制在 [MinZoom=0.1, MaxZoom=100] 范围内;④ 计算让该区域中心映射到 inner 中心所需的 _offset;⑤ 重绘
返回前提若 Image == null、参数区域无效或边框内侧为空,则不执行任何操作
典型场景缩放定位到某块细节(如“定位到面部”),或与蚂蚁线联动“把框选区域放大到视口中心”
// 把原图 (100, 200, 300, 400) 区域居中放大显示
pb.ShowImageRegion(new Rectangle(100, 200, 300, 400));

// 与蚂蚁线联动
pb.AntLine.Visible = true;
pb.AntLine.AntRect = new Rectangle(50, 50, 200, 150);

// 把蚂蚁线框出的原图区域居中显示 —— 注意:AntRect 若以控件坐标而非原图坐标表示,需先转换
pb.ShowImageRegion(pb.AntLine.AntRect);

注意:ShowImageRegion 的参数是原图像素坐标,而不是控件客户区坐标。如果从蚂蚁线(以控件坐标表示)拿到的矩形,需要先通过 GetImageInRectangle 之类的反算逻辑映射到原图坐标后再传入。


六、公开成员速查表

成员类型说明
PictureBox()构造函数创建控件(150×150,默认边框 6,默认 BackColor 深灰)
ImageSizeMode属性图片显示方式(Stretch / Zoom / None / Center)
Image属性图片;赋值触发 Change 事件
BorderSize属性边框粗细(像素,默认 6)
BorderColor属性(ARGB)边框颜色
BackColor属性(重写)背景颜色
MouseEnabled属性是否启用左键拖动 + 滚轮缩放 + 右键复位
RightRestore属性右键是否复位(仅 MouseEnabled=true 有效)
AntLine属性蚂蚁线子控件;用于选框联动、区域裁剪
Change事件图片被赋值时触发
Redraw()方法复位缩放/平移,并重绘
GetImageDisplayRectangle()方法返回当前图片实际绘制矩形(含缩放平移)
GetVisibleImageRectangle()方法返回图片在控件可视范围内的部分
GetImageInRectangle(Rectangle)方法提取指定控件区域内显示的原图内容为 Bitmap(调用方 Dispose)
ShowImageRegion(Rectangle)方法自动计算缩放平移,使指定原图区域居中放大显示

七、鼠标交互一览

操作前提效果
鼠标进入控件MouseEnabled=true 且 CanFocus=true自动 Focus(),保证滚轮事件可接收
左键按下MouseEnabled=true 且有图片进入拖动状态,光标变为 SizeAll,鼠标捕获
左键拖动拖动状态中更新 _offset(基于鼠标位移增量),实时重绘
左键抬起拖动状态中结束拖动,光标恢复 Default,释放捕获
滚轮向前(Delta>0)MouseEnabled=true 且有图片以鼠标位置为中心放大 1.1 倍(最大 100×)
滚轮向后(Delta<0)同上以鼠标位置为中心缩小 1/1.1 倍(最小 0.1×)
右键抬起MouseEnabled=true 且 RightRestore=true调用 Redraw() 复位缩放与平移

缩放算法说明:滚轮缩放时以“鼠标所在的控件坐标”为不动点,通过公式 _offset' = (1 - k) * (mouse - center) + k * _offset(k = newZoom / oldZoom)更新偏移,保证鼠标指向的图像细节在缩放前后位置不变。


八、完整使用示例

示例 1:基础图片浏览

var pb = new PictureBox
{
    Parent = this,
    Dock = DockStyle.Fill,
    Image = Image.FromFile("test.png"),
    ImageSizeMode = CConPlus.Enum.ImageSizeMode.Zoom,
    BorderSize = 4,
    BorderColor = Color.FromArgb(255, 80, 80, 80),
    BackColor = Color.Black
};

示例 2:可拖动 / 缩放的图片查看器

var pb = new PictureBox
{
    Parent = this,
    Dock = DockStyle.Fill,
    ImageSizeMode = CConPlus.Enum.ImageSizeMode.None,
    MouseEnabled = true,      // 开启鼠标拖动 + 滚轮缩放
    RightRestore = true,      // 右键复位
    BorderSize = 2
};
pb.Image = Image.FromFile("map.png");

// 外部按钮复位
btnReset.Click += (s, e) => pb.Redraw();

// 外部按钮“聚焦到某块区域”
btnFocus.Click += (s, e) => pb.ShowImageRegion(new Rectangle(200, 200, 400, 300));

示例 3:配合蚂蚁线裁剪

var pb = new PictureBox { Parent = this, Dock = DockStyle.Fill, MouseEnabled = true };
pb.Image = Image.FromFile("photo.jpg");
pb.AntLine.Visible = true;

btnCrop.Click += (s, e) =>
{
    Rectangle r = pb.AntLine.AntRect;
    if (r.Width > 0 && r.Height > 0)
    {
        using (Bitmap bmp = pb.GetImageInRectangle(r))
        {
            if (bmp != null)
            {
                bmp.Save("cropped.png", System.Drawing.Imaging.ImageFormat.Png);
                MessageBox.Show("已保存 cropped.png");
            }
        }
    }
};

示例 4:监听图片变化自动复位

var pb = new PictureBox { Parent = this, Dock = DockStyle.Fill, MouseEnabled = true };

pb.Change += (s, e) =>
{
    // 换图后回到初始视角
    pb.Redraw();
};

// 之后每次设置 pb.Image 都会触发 Change → 自动复位
pb.Image = Image.FromFile("a.png");
pb.Image = Image.FromFile("b.png");

示例 5:将鼠标控件坐标转换为原图坐标

// 通过 GetImageInRectangle + 反算,可以把一个“控件坐标”区域
// 转换成原图内容;如果只需要坐标映射,可以这样:
Rectangle disp = pb.GetImageDisplayRectangle();
Rectangle inner = CConPlus.Rect.MoveRectangleInward(pb.ClientRectangle, pb.BorderSize);

// 例:假设鼠标位置 mouseCtrl 是控件坐标,判断它是否落在图片上:
Point mouseCtrl = PointToClient(Cursor.Position);
bool onImage = disp.Contains(mouseCtrl);

// 若需要计算该点对应的原图像素坐标,可以复用 GetImageInRectangle 的裁剪结果
// 或者直接参考 GetImageInRectangle 内部的反变换公式

九、注意事项

  1. Image 属性:控件不负责 Dispose 传入的图片;需要更换图片时,自行释放旧图,否则会内存泄漏。

  2. BorderSize 未校验上下限:请保证非负,且不要大于控件尺寸的一半,否则会出现 MoveRectangleInward 返回空矩形、或 Pen 绘制异常。

  3. AntLine setter 行为:_antLineControl = value; Controls.Add(value); 不检查是否已添加;多次赋值会在 Controls 中叠加多个 AntLine。建议只读用途,直接用构造时创建的那个实例。

  4. Change 事件一定会触发:即使赋相同引用也会触发(setter 无“值相同”判断)。若你需要“仅在真正换图时才响应”,需要自己记录旧引用做比对。

  5. 滚轮缩放需要焦点:控件设置了 Selectable + TabStop=true;MouseEnabled=true 时鼠标进入会自动 Focus(),确保滚轮消息进入控件。若在容器内被其它控件抢占焦点,可能需手动 pb.Focus()。

  6. ShowImageRegion 使用原图坐标:不是控件坐标。如果从 AntLine.AntRect(通常是控件坐标)取区域,需要先反算回原图坐标。

  7. GetImageInRectangle 的返回 Bitmap 需要调用方 Dispose:这是常见的 WinForms 内存泄漏点。

  8. 缩放范围:硬编码为 [0.1×, 100×],不可通过属性调整。ShowImageRegion 计算出的缩放比例也会被 clamp 到该范围。

  9. ImageSizeMode 的具体行为:绘制由 CConPlus.GraphicsC.DrawImageInRect 实现;本控件的 GetImageDisplayRectangle / GetImageInRectangle 会按照 Stretch / Zoom / 其他 三种情况近似反算。**如果 CConPlus 的 DrawImageInRect 对某些模式有额外处理**(如 Tile),需要相应调整 CalcImageRectInInner。

  10. 右键复位只针对“鼠标操作”引起的缩放/平移;如果你通过代码手动设置过 ShowImageRegion,那么右键复位会把视角还原到“无缩放、无平移”的初始状态,而不是回到那次 ShowImageRegion 的状态。

  11. BorderColor 支持 ARGB(透明边框可出现穿透背景效果),而 BackColor 保持普通 Color 编辑。


转载请注明出处。

本文链接:http://www.pythonopen.com/?id=7971

相关文章

已经实现的一些算法

编码CConA1是一种可复原的编码算法,用于将文本或字节转换为纯字母。可用于文件名混淆,避免因包含违...

横向滚动条HScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

纵向滚动条VScrollBar 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control版本:基于所提供...

菜单MenuItem 与 ContextMenu 控件调用文档

命名空间:CConUI依赖:System.Windows.Forms、System.Drawing、...

蚂蚁线AntLine 控件调用文档

命名空间:CConUI继承:System.Windows.Forms.Control定位:虚线蚂蚁线...