项目 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>
This commit is contained in:
1 parent
4ed9450c02
commit
6b088240da
76 files changed
+1290
-14
No files matched your search
@@ -31,6 +31,7 @@ public static class PropValue
|
||||
["underline"] = f.Underline,
|
||||
["strikeout"] = f.Strikeout,
|
||||
},
|
||||
Image image => new JsonObject { ["key"] = SimHost.ImageKey(image), ["width"] = image.Width, ["height"] = image.Height },
|
||||
Padding p => new JsonObject { ["left"] = p.Left, ["top"] = p.Top, ["right"] = p.Right, ["bottom"] = p.Bottom },
|
||||
IEnumerable list => ListOf(list),
|
||||
_ => JsonValueOf(value.ToString() ?? ""),
|
||||
|
||||
@@ -75,6 +75,42 @@ public static class SimHost
|
||||
_output.WriteLine(new JsonObject { ["type"] = "patch", ["changes"] = changes }.ToJsonString(JsonOptions));
|
||||
}
|
||||
|
||||
// ---------- 图片 ----------
|
||||
|
||||
private static readonly HashSet<string> SentImages = new();
|
||||
|
||||
/// <summary>
|
||||
/// 学生程序的"程序所在目录"(AppDomain.CurrentDomain.BaseDirectory),可写,程序结束后清掉。
|
||||
/// 运行器启动时设定;保存的图片按相对这里的路径显示在网页的照片列表里。
|
||||
/// </summary>
|
||||
public static string AppBaseDirectory { get; set; } = AppContext.BaseDirectory;
|
||||
|
||||
/// <summary>图片在浏览器端的编号;第一次用到时先把图片数据发过去,浏览器缓存后同一张图不再重发</summary>
|
||||
public static string ImageKey(System.Drawing.Image image)
|
||||
{
|
||||
var key = image.SimKey;
|
||||
bool isNew;
|
||||
lock (SentImages) isNew = SentImages.Add(key);
|
||||
if (isNew)
|
||||
{
|
||||
Send(new JsonObject
|
||||
{
|
||||
["type"] = "image",
|
||||
["key"] = key,
|
||||
["mime"] = image.MimeType,
|
||||
["data"] = Convert.ToBase64String(image.Data),
|
||||
});
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/// <summary>学生程序用 Image.Save 保存了图片:网页的照片列表里显示出来</summary>
|
||||
public static void ImageSaved(string fullPath, System.Drawing.Image image)
|
||||
{
|
||||
var path = fullPath.StartsWith(AppBaseDirectory, StringComparison.Ordinal) ? fullPath[AppBaseDirectory.Length..] : fullPath;
|
||||
Send(new JsonObject { ["type"] = "imageSaved", ["path"] = path, ["image"] = ImageKey(image) });
|
||||
}
|
||||
|
||||
public static void SendConsole(string text) => Send(new JsonObject { ["type"] = "console", ["text"] = text });
|
||||
|
||||
public static void SendDevice(string device, string action, object? data)
|
||||
|
||||
Reference in new issue
Block a user