Android中如何将ByteString转换为图片?
从Socket接收的ByteString中提取图片的解决方案
核心分析
你收到的字符串是带元信息的十六进制拼接内容:[size=xxxhex=|ServerReturnDir=xxx|ImageFileName=xxx|图片十六进制数据](其中7c是ASCII字符|的十六进制编码)。关键是要剥离前面的元信息,提取出图片的原始十六进制数据,再转换为字节数组生成图片。
具体步骤
1. 提取Hex字段内容
从收到的消息字符串中,截取hex=之后到]之前的所有字符,得到完整的十六进制拼接串。
2. 分离图片的十六进制数据
找到拼接串中最后一个7c(对应|)的位置,截取该位置之后的所有字符——这部分就是图片的原始十六进制数据(前面的030905是控制字符,JPG解码器会自动跳过,真正的图片起始标记是FFD8)。
3. 十六进制转字节数组
将提取到的图片十六进制字符串,每两个字符转换为一个字节,组成字节数组(若长度为奇数,补一个0保证转换正常)。
4. 生成图片文件
将字节数组写入文件,文件名可从元信息中提取(比如ImageFileName=Image_001.jpg)。
代码示例
Python实现
# 假设socket收到的消息为msg msg = "[size=302697hex=7c53657276657252657475726e4469723d54454d505f4449527c496d61676546696c654e616d653d496d6167655f3030312e6a70677c030905ffd8ffe000104a…]" # 提取hex部分 hex_content = msg.split('hex=')[1].rstrip(']') # 截取最后一个|之后的图片十六进制数据 last_sep_pos = hex_content.rfind('7c') image_hex = hex_content[last_sep_pos + 2:] # 处理奇数长度的十六进制串 if len(image_hex) % 2 != 0: image_hex += '0' # 转换为字节数组 image_bytes = bytes.fromhex(image_hex) # 提取文件名并写入文件 filename_segment = hex_content.split('7c')[2] filename = filename_segment.split('=')[1] with open(filename, 'wb') as f: f.write(image_bytes)
Java实现
import java.io.FileOutputStream; import java.io.IOException; public class SocketImageParser { public static void main(String[] args) { String socketMsg = "[size=302697hex=7c53657276657252657475726e4469723d54454d505f4449527c496d61676546696c654e616d653d496d6167655f3030312e6a70677c030905ffd8ffe000104a…]"; // 提取hex字段内容 String hexPart = socketMsg.split("hex=")[1].replace("]", ""); // 截取图片的十六进制数据 int lastSeparatorIndex = hexPart.lastIndexOf("7c"); String imageHex = hexPart.substring(lastSeparatorIndex + 2); // 处理奇数长度 if (imageHex.length() % 2 != 0) { imageHex += "0"; } // 十六进制转字节数组 byte[] imageBytes = new byte[imageHex.length() / 2]; for (int i = 0; i < imageBytes.length; i++) { int index = i * 2; int byteValue = Integer.parseInt(imageHex.substring(index, index + 2), 16); imageBytes[i] = (byte) byteValue; } // 提取文件名并写入文件 String filenameSegment = hexPart.split("7c")[2]; String filename = filenameSegment.split("=")[1]; try (FileOutputStream fos = new FileOutputStream(filename)) { fos.write(imageBytes); } catch (IOException e) { e.printStackTrace(); } } }
注意事项
- 若生成的图片无法打开,检查是否正确截取了图片的十六进制数据,或是否存在非法十六进制字符。
- 可通过文件头验证:JPG的起始标记为
FFD8,PNG为89504E47,确保提取的hex包含对应标记。
内容的提问来源于stack exchange,提问作者Ravi Makvana
相关产品推荐
相关产品推荐

