需求描述:
浏览器中的网页在调用本地客户端程序进行身份证读卡后,将读卡获取的图片发送至浏览器页面中,然后显示读到的身份证照片。
过程描述
- 浏览器通过注册表协议打开本地程序,并发送读取身份证的业务请求(之前已经实现,不在本次总结范围内);
- 客户端进行身份证读卡获取身份证信息(包括照片);
- 将照片进行base64编码,并合并其它信息转成json格式通过http请求发送至系统的后端(之前已经实现,不在本次总结范围内);
- 系统后端通过websocket的方式将客户端发送的身份证信息通知给浏览器页面;
- 浏览器页面获取websocket发来的身份证信息(json格式),将其中的各项信息显示到页面中(包括照片)。
照片传输技术拆解
- 首先winform客户端需要将读卡器读出的bmp格式图片转成png(因为bmp格式web前端不支持直接显示此格式,并且文件极大实测100k的身份证照片在转为png后仅为3k),然后根据png再转为byte[],因为前台在展示时采用<img src='data:image/png;base64, xxx'>方式进行显示,编码方式如下所示,并不是直接转码,感觉绕了一点路,但是最终实现目的:
// c# 代码
Image newImage;
// 获取读卡后本地bmp格式的照片信息
using (FileStream fileStream = new FileStream(Application.StartupPath + "\\zp.bmp", FileMode.Open, FileAccess.Read))
{
Bitmap bmp = new Bitmap(fileStream);
// 得到原图
Image image = bmp;
// 创建指定大小的图
newImage = image.GetThumbnailImage(bmp.Width, bmp.Height, null, new IntPtr());
Graphics g = Graphics.FromImage(newImage);
//将原图画到指定的图上
g.DrawImage(newImage, 0, 0, newImage.Width, newImage.Height);
g.Dispose();
// 转码为png格式,并保存在本地
newImage.Save(Application.StartupPath + "\\zp.png", ImageFormat.Jpeg);
}
// 读取png格式的图片,然后转为byte[]格式
using (FileStream stream = new FileStream(Application.StartupPath + "\\zp.png", FileMode.Open, FileAccess.Read))
{
int byteLength = (int)stream.Length;
byte[] photoBytes = new byte[byteLength];
stream.Read(photoBytes, 0, byteLength);
idCardInfo.Photo = photoBytes;
}
- 然后再将byte[]格式的图片转码为base64:
// c# 代码
/// <summary>
/// 身份证信息
/// </summary>
public struct IdCardInfo
{
[JsonProperty(PropertyName = "id")]
public string Id;
[JsonProperty(PropertyName = "name")]
public string Name;
[JsonProperty(PropertyName = "birthday")]
[JsonConverter(typeof(SecondEpochConverter))]
public DateTime BirthDate;
// ...略 其它身份证信息
[JsonProperty(PropertyName = "photo")]
[JsonConverter(typeof(ByteArrayToStringConverter))]
public byte[] Photo;
}
using Newtonsoft.Json;
using System;
/// <summary>
/// byte[]转base64转码器
/// </summary>
class ByteArrayToStringConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
byte[] b = (byte[])value;
writer.WriteRawValue("\"" + Convert.ToBase64String(b) + "\"");
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value;
}
public override bool CanConvert(Type objectType)
{
if (objectType == new byte[0].GetType())
{
return true;
}
return false;
}
}
- 再通过JSON.NET将其转换为json格式的数据返回至前端:
// c# 代码
notice.RouteParams = JsonConvert.SerializeObject(_idCardInfo);
- web前端将得到的base64编码的图片通过<img>标签展示到页面中(MVVM框架,双向绑定src):
// javascript 代码
// params.photo即客户端传过来的base64编码的photo
this.imageUrl = 'data:image/png;base64,' + params.photo;
// vue模板代码
<img v-if="imageUrl" :src="imageUrl">
网友评论