C#中十六进制字符串长度为奇数时如何转换为BitmapImage?
解决WPF中奇数长度十六进制字符串转BitmapImage的问题
问题根源
原代码仅支持偶数长度的十六进制字符串,当长度为奇数时,整数除法会丢弃最后一个字符;直接在字符串末尾补0会导致字节数据错位,破坏图像原始结构,最终生成不完整的图像。
正确解决方案
核心是在奇数长度的十六进制字符串开头补0(而非末尾),保证每两个字符对应一个字节,维持原始数据的字节顺序。同时添加输入校验和错误处理,提升代码健壮性。
修改后的代码
public BitmapImage StringToImage(string hex) { if (string.IsNullOrWhiteSpace(hex)) throw new ArgumentException("十六进制字符串不能为空或仅含空白字符。", nameof(hex)); // 过滤无效字符,仅保留合法十六进制字符 var cleanHex = new string(hex.Where(c => char.IsDigit(c) || (char.ToUpperInvariant(c) >= 'A' && char.ToUpperInvariant(c) <= 'F')).ToArray()); if (cleanHex.Length == 0) throw new FormatException("十六进制字符串中无有效字符。"); // 奇数长度时在开头补0,确保字节转换的正确性 if (cleanHex.Length % 2 != 0) { cleanHex = "0" + cleanHex; } byte[] bytes = new byte[cleanHex.Length / 2]; try { for (int i = 0; i < cleanHex.Length; i += 2) { bytes[i / 2] = Convert.ToByte(cleanHex.Substring(i, 2), 16); } } catch (FormatException ex) { throw new FormatException("十六进制字符串格式无效。", ex); } using (var ms = new System.IO.MemoryStream(bytes)) { var image = new BitmapImage(); try { image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; image.StreamSource = ms; image.EndInit(); return image; } catch (Exception ex) { throw new InvalidOperationException("无法将字节数组转换为BitmapImage。", ex); } } }
关键说明
十六进制字符串的字节顺序是从左到右对应高位到低位,比如奇数长度字符串"F12"应被解析为"0F12",对应字节0x0F和0x12;若在末尾补0变为"F120",则对应字节0xF1和0x20,完全改变了原始图像数据的结构,导致图像解析异常。
内容的提问来源于stack exchange,提问作者Jorne
相关产品推荐
相关产品推荐

