Files
xuyueandClaude Opus 5.5 6b088240da
CI/CD / test (push) Canceled after 0s
CI/CD / deploy (push) Canceled after 0s
项目 4 任务 2 网络摄像机:PictureBox、Image / Bitmap、照片列表
- 摄像头:自绘东围墙场景(Camera/scene.svg),按云台位置切成 640×480 帧(build-frames.ts);
  Pan 每次转一格,红外对射被遮挡时画面出现翻墙的人;类名、委托、事件参数与教材 dll 一致,
  ImageRead 每 250 ms 在后台线程触发
- Image / Bitmap 保存真实图片数据:Save、FromFile、FromStream,文件夹不存在时报 GDI+ 一般性错误;
  图片每张只发给浏览器一次(按内容哈希缓存)
- 程序所在目录(AppDomain.CurrentDomain.BaseDirectory,编译检查单独放行)和当前目录指向可写的 bin/Debug,
  沙箱里在沙箱的临时目录
- PictureBox(SizeMode、BorderStyle);设计器工具箱加"图片框";运行区显示程序保存的图片,点开看大图;
  实训台摄像头图标显示开启状态
- 评分规则加图片框显示图片、摄像头开关与转向、保存图片三种检查;示例 p4-t2-网络摄像机
- 测试:摄像头端到端、图片读写与程序目录、AppDomain 编译检查、评分出错情况

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:58:09 +08:00

85 lines
2.4 KiB
C#

using System.ComponentModel;
using System.Drawing;
using System.Text.Json.Nodes;
using Sim.Host;
namespace System.Windows.Forms;
public enum PictureBoxSizeMode { Normal, StretchImage, AutoSize, CenterImage, Zoom }
/// <summary>图片框(教材项目 4 显示摄像头画面)</summary>
public class PictureBox : Control, ISupportInitialize
{
private Image? _image;
private PictureBoxSizeMode _sizeMode;
private BorderStyle _borderStyle;
protected override Size DefaultSize => new(100, 50);
/// <summary>
/// 要显示的图片。不检查调用线程:教材在摄像头回调(后台线程)里直接给 Image 赋值,
/// 真实 WinForms 的 PictureBox 也不会因此报错。
/// </summary>
public Image? Image
{
get => _image;
set
{
LegacyThreads.CheckPoint();
if (ReferenceEquals(_image, value)) return;
_image = value;
NotifyChanged(nameof(Image), value);
if (_sizeMode == PictureBoxSizeMode.AutoSize) FitToImage();
}
}
public PictureBoxSizeMode SizeMode
{
get => _sizeMode;
set
{
if (SetProp(ref _sizeMode, value, nameof(SizeMode)) && value == PictureBoxSizeMode.AutoSize) FitToImage();
}
}
public BorderStyle BorderStyle
{
get => _borderStyle;
set => SetProp(ref _borderStyle, value, nameof(BorderStyle));
}
public string? ImageLocation { get; set; }
public Image? ErrorImage { get; set; }
public Image? InitialImage { get; set; }
public bool WaitOnLoad { get; set; }
/// <summary>从文件加载图片(只支持本地文件)</summary>
public void Load(string url)
{
ImageLocation = url;
Image = Image.FromFile(url);
}
public void Load()
{
if (!string.IsNullOrEmpty(ImageLocation)) Load(ImageLocation);
}
// Designer.cs 里 VS 生成 ((ISupportInitialize)pictureBox1).BeginInit() / EndInit()
public void BeginInit() { }
public void EndInit() { }
private void FitToImage()
{
if (_image != null) Size = _image.Size;
}
protected override void WriteProps(JsonObject props)
{
base.WriteProps(props);
props["Image"] = PropValue.From(_image);
props["SizeMode"] = _sizeMode.ToString();
props["BorderStyle"] = _borderStyle.ToString();
}
}