C#咨询:签名图片低字符量可序列化存储解决方案
低字符量可序列化的收据签名图片存储方案
核心思路:针对性图片压缩+高效编码
签名图片以线条为主,天生适合做轻量化处理,配合比Base64更高效的编码方式,能大幅降低传输体积,同时保证JSON序列化兼容性。
1. 先对签名图片做针对性压缩
签名是单色线条图,无需保留冗余色彩和分辨率:
- 转1-bit单色位图:将彩色/灰度签名转为纯黑白格式,体积直接降至原灰度图的1/8、彩色图的1/24。
- 降低分辨率:签名不需要高DPI,比如从1080p缩至320x240,体积按比例缩小。
- 用PNG格式存储:PNG对线条图的压缩率远高于JPG,不会模糊签名线条。
2. 替换Base64,用更高效的编码方式
Base64会让体积额外增加33%,可以选择以下更紧凑的编码,同时兼容JSON:
- Base85编码:比Base64更高效,体积仅增加25%,主流编程语言都有现成库支持(如Python的
base64.b85encode、C#的Base85类)。 - 二进制序列化协议:如果API允许非JSON格式,直接用MessagePack或Protocol Buffers序列化,体积比JSON+Base64小一半以上;若必须用JSON,可将压缩后的图片字节用Base85编码后嵌入JSON。
3. 实现示例(以C#为例)
// 1. 处理签名图片:转单色+压缩 Bitmap originalSignature = ...; using (Bitmap monoBitmap = new Bitmap(originalSignature.Width, originalSignature.Height, PixelFormat.Format1bppIndexed)) { using (Graphics g = Graphics.FromImage(monoBitmap)) { g.Clear(Color.White); g.DrawImage(originalSignature, new Rectangle(0, 0, monoBitmap.Width, monoBitmap.Height)); } // 保存为PNG到内存流 using (MemoryStream ms = new MemoryStream()) { monoBitmap.Save(ms, ImageFormat.Png); byte[] compressedBytes = ms.ToArray(); // 2. 用Base85编码替代Base64 string encodedString = System.Text.Encoding.ASCII.GetString(Base85.Encode(compressedBytes)); // 3. 嵌入JSON提交API var receiptData = new { Id = "receipt_123", Signature = encodedString }; string json = JsonSerializer.Serialize(receiptData); // 提交API逻辑... } }
4. 服务器端反序列化
string encodedSignature = ...; // 从JSON中提取 byte[] compressedBytes = Base85.Decode(System.Text.Encoding.ASCII.GetBytes(encodedSignature)); using (MemoryStream ms = new MemoryStream(compressedBytes)) { Bitmap signatureBitmap = new Bitmap(ms); // 存储或展示签名逻辑... }
额外优化建议
- 若API支持分块上传,可将超大图片拆分分批传输,但签名图压缩后体积通常很小,无需此操作。
- 禁止直接序列化Bitmap对象:JSON无法处理复杂对象,必须转成字节或编码后的字符串。
内容的提问来源于stack exchange,提问作者Gouvo
相关产品推荐
相关产品推荐

