C#条码考勤系统:扫描条码后从MySQL自动调取对应学生BLOB图片的实现方法
C#条码考勤系统读取BLOB格式学生照片实现方案
现有代码的待优化点
在实现照片展示功能前,先修正原有代码的几处逻辑问题:
- 原代码查询时使用未更新的
textBox1.Text做模糊匹配,实际查询条件应该以扫码成功获取的条码内容为准,容易出现匹配错误 - 原有全局共享的MySqlCommand、数据库连接对象在多线程调用场景下,容易出现连接占用、对象释放异常
- 字符串拼接SQL的写法存在SQL注入风险,需要替换为参数化查询
核心实现步骤
要实现扫描条码后自动展示对应学生照片,流程为:
- 界面上新增一个独立的
PictureBox控件(建议命名为picStudentPhoto)专门用于展示学生照片,和原有用于显示摄像头实时画面的pictureBox1做功能区分 - 以扫码得到的学生ID作为参数查询数据库,查询结果中包含
imageBLOB字段 - 将BLOB字段读取为字节数组,通过内存流转为可绑定的图片对象,赋值给对应的PictureBox控件
修正后的完整可运行代码
private void VideoCaptureDevice_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs) { Bitmap cameraFrame = (Bitmap)eventArgs.Frame.Clone(); BarcodeReader reader = new BarcodeReader(); var scanResult = reader.Decode(cameraFrame); // 增加同条码去重判断,避免连续帧重复触发数据库查询 if (scanResult != null && scanResult.Text != textBox1.Text) { textBox1.Invoke(new MethodInvoker(delegate () { string scannedStudentId = scanResult.Text.Trim(); // 先清空上一位学生的缓存信息 label3.Text = string.Empty; label4.Text = string.Empty; label8.Text = string.Empty; picStudentPhoto.Image = null; // 使用using块自动释放数据库资源,避免连接泄漏 using (MySqlConnection con = new MySqlConnection("你的数据库连接字符串")) { // 参数化查询替代字符串拼接,规避SQL注入 string sqlStr = "SELECT std_name, std_nic, batch, image FROM std_info WHERE nibm_id = @StudentId"; using (MySqlCommand cmd = new MySqlCommand(sqlStr, con)) { cmd.Parameters.AddWithValue("@StudentId", scannedStudentId); con.Open(); using (MySqlDataReader dr = cmd.ExecuteReader()) { if (dr.Read()) { // 基础信息赋值 textBox1.Text = scannedStudentId; label3.Text = dr["std_name"].ToString(); label4.Text = dr["std_nic"].ToString(); label8.Text = dr["batch"].ToString(); // 读取BLOB字段存储的学生照片 if (!dr.IsDBNull(dr.GetOrdinal("image"))) { // 获取图片总字节长度 long photoByteLength = dr.GetBytes(dr.GetOrdinal("image"), 0, null, 0, 0); byte[] photoBytes = new byte[photoByteLength]; // 将BLOB数据读到字节数组 dr.GetBytes(dr.GetOrdinal("image"), 0, photoBytes, 0, (int)photoByteLength); // 字节流转内存流,生成图片对象显示 using (MemoryStream ms = new MemoryStream(photoBytes)) { picStudentPhoto.Image = Image.FromStream(ms); } } } } } } })); } // 摄像头实时画面绑定到原有pictureBox1 pictureBox1.Image = cameraFrame; }
开发注意事项
- 确保存入数据库
image字段的内容是标准图片格式(JPG/PNG等)的二进制流,不要存储图片的本地文件路径,否则无法正常转成图片对象显示 - 两个PictureBox控件不要混淆功能:原有
pictureBox1用于显示扫码摄像头的实时取景内容,新增的picStudentPhoto用于展示数据库中存储的学生证件照 - 如果数据库中存储的照片尺寸过大,可以在上传时提前压缩图片分辨率,减少BLOB字段的存储体积,加快图片加载速度
- 扫码逻辑增加去重判断后,不会因为摄像头连续帧扫描到同一条码就反复查询数据库,能明显降低数据库的查询压力
内容的提问来源于stack exchange,提问作者Sachintha Senanayake
相关产品推荐
相关产品推荐

