- 摄像头:自绘东围墙场景(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>
85 lines
2.4 KiB
C#
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();
|
|
}
|
|
}
|