Java 将十六进制字符串转换为图像文件
我需要从接收到的xml文件中读取一个前导为零的十六进制字符串,该字符串表示JPEG文件,并将其保存为图像文件。图像数据看起来像Java 将十六进制字符串转换为图像文件,java,hex,Java,Hex,我需要从接收到的xml文件中读取一个前导为零的十六进制字符串,该字符串表示JPEG文件,并将其保存为图像文件。图像数据看起来像 0000005000000050FF191818FF151715FF111413FF0E1...........................FF2A2322FF292221 在xml文件中,标记之间的字符串长度为51216。我将照片标记之间的十六进制数据读取为字符串,并将其转换为字节[],然后使用FileOutputStream写入文件。但当我试图打开图像文件时,
0000005000000050FF191818FF151715FF111413FF0E1...........................FF2A2322FF292221
在xml文件中,标记之间的字符串长度为51216。我将照片标记之间的十六进制数据读取为字符串,并将其转换为字节[],然后使用FileOutputStream
写入文件。但当我试图打开图像文件时,它会告诉我“文件似乎已损坏、损坏或文件太大”,我尝试了许多方法来保存图像,但没有成功。我在下面列出了使用的方法。请帮我解决这个问题
String photo="0000005000000050FF191818FF15"; //this is just a sample.The photo String actually contains the full Hex String which is 51216 long
//METHOD 1
String[] v = photo.split(" ");
byte[] arr = new byte[v.length];
int x = 0;
for(String val: v) {
arr[x++] = Integer.decode("0x" + val).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(arr);
fos.flush();
fos.close();
//METHOD 2
byte[] arr = new byte[photo.length()/2];
for ( int start = 0; start < photo.length(); start += 2 )
{
String thisByte = photo.substring(start, start+2);
arr[start/2] = Byte.parseByte(thisByte, 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(arr);
fos.flush();
fos.close();
//METHOD 3
if ((photo.length() % 2) != 0)
throw new IllegalArgumentException("Input string must contain an even number of characters");
final byte result[] = new byte[photo.length()/2];
final char enc[] = photo.toCharArray();
for (int x = 0; x < enc.length; x += 2)
{
StringBuilder curr = new StringBuilder(2);
curr.append(enc[x]).append(enc[x + 1]);
result[x/2] = (byte) Integer.parseInt(curr.toString(), 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(result);
fos.flush();
fos.close();
//METHOD 4
byte result[] = new byte[photo.length()/2];
char enc[] = photo.toUpperCase().toCharArray();
StringBuffer curr;
for (int x = 0; x < enc.length; x += 2)
{
curr = new StringBuffer("");
curr.append(String.valueOf(enc[x]));
curr.append(String.valueOf(enc[x + 1]));
result[x] = (byte) Integer.parseInt(curr.toString(), 16);
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(result);
fos.flush();
fos.close();
//METHOD 5
int len = photo.length();
byte[] data = new byte[len / 2];
for (int x = 0; x < len; x += 2)
{
data[x / 2] = (byte) ((Character.digit(photo.charAt(x), 16) << 4)
+ Character.digit(photo.charAt(x+1), 16));
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 6
byte[] bytes=new BigInteger(photo, 16).toByteArray();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 7
byte[] bytes =DatatypeConverter.parseHexBinary(photo);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 8
HexBinaryAdapter adapter = new HexBinaryAdapter();
byte[] bytes = adapter.unmarshal(photo);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.png");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 9
byte data[] = new byte[photo.length()/2];
for(int x=0;i < photo.length();x+=2) {
data[x/2] = (Integer.decode("0x"+photo.charAt(x)+photo.charAt(x+1))).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 10
byte[] data = new byte[photo.length()/2];
for (int x=0;i<photo.length()/2;x++)
{
data[x] = (Integer.decode(
"0x"+photo.substring(x*2, (x+1)*2))).byteValue();
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(data);
fos.flush();
fos.close();
//METHOD 11
String hexVal ="0000005000000050FF";
//String hexVal = "0123456789ABCDEF";
byte[] out = new byte[photo.length() / 2];
int n = photo.length();
for( int x = 0; x < n; x += 2 ) {
int hn = hexVal.indexOf( photo.charAt( x ) );
int ln = hexVal.indexOf( photo.charAt( x + 1 ) );
out[x/2] = (byte)( ( hn << 4 ) | ln );
}
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(out);
fos.flush();
fos.close();
//METHOD 12
byte[] array=photo.getBytes();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(array);
fos.flush();
fos.close();
//METHOD 13
byte[] array=photo.getBytes();
byte[] bytes = Base64.decode(array);
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(bytes);
fos.flush();
fos.close();
//METHOD 14
byte[] array=photo.getBytes();
Charset csets = Charset.forName("UTF-8");
ByteBuffer bb=ByteBuffer.wrap(array);
csets.decode(bb);
bb.rewind();
byte[] array1=bb.array();
FileOutputStream fos=new FileOutputStream("D:/Images/image6.jpg");
fos.write(array1);
fos.flush();
fos.close();
String photo=“0000005000000050FF191818FF15”//这只是一个示例。照片字符串实际上包含长度为51216的完整十六进制字符串
//方法1
字符串[]v=photo.split(“”);
字节[]arr=新字节[v.length];
int x=0;
用于(字符串val:v){
arr[x++]=Integer.decode(“0x”+val).byteValue();
}
FileOutputStream fos=新的FileOutputStream(“D:/Images/image6.jpg”);
fos.write(arr);
fos.flush();
fos.close();
//方法2
字节[]arr=新字节[photo.length()/2];
对于(int start=0;start 数据[x/2]=(字节)((Character.digit)(photo.charAt(x),16)最短的路径可能是这样
String photo = "0000005000000050FF191818FF151715FF111413FF0E100FF2A2322FF292221";
// adds a dummy byte at the start to avoid truncation of leading zeros.
byte[] bytes = new BigInteger("10" + photo, 16).toByteArray();
System.out.println(Arrays.toString(bytes));
印刷品
[1,0,0,0,5,0,0,0,5,15,-15,-111,-127,-113,-15,81,113,95,-15,17,65,63,-16,-31,0,-1,42,35,34,-1,41,34,33]公共类测试{
public class test {
static String HEX_STRING = "0123456789ABCDEF";
public static byte[] convertHexadecimal2Binary(byte[] hex) {
int block = 0;
byte[] data = new byte[hex.length / 2];
int index = 0;
boolean next = false;
for (int i = 0; i < hex.length; i++) {
block <<= 4;
int pos = HEX_STRING.indexOf(Character.toUpperCase((char) hex[i]));
if (pos > -1) {
block += pos;
}
if (next) {
data[index] = (byte) (block & 0xff);
index++;
next = false;
} else {
next = true;
}
}
return data;
}
public static void main(String args[]) {
String line = "";
String line_final = "";
try {
String sCurrentLine;
BufferedReader br = new BufferedReader(new FileReader("D:\\test.txt"));//test.txt hex code string
DataOutputStream os = new DataOutputStream(new FileOutputStream("D:\\mohit.jpg"));
while ((sCurrentLine = br.readLine()) != null) {
line = StringUtils.deleteWhitespace(sCurrentLine);
byte[] temp = convertHexadecimal2Binary(line.getBytes());
os.write(temp);
}
os.close();
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
静态字符串HEX_String=“0123456789ABCDEF”;
公共静态字节[]转换器十六进制2二进制(字节[]十六进制){
int block=0;
字节[]数据=新字节[hex.length/2];
int指数=0;
布尔下一个=假;
对于(int i=0;i block检索文件时,将在十六进制字符串的开头追加一个空格,因此请删除该空格并将其存储在另一个字节数组中,这样就可以正常工作:
下面是删除起始空间的代码
byte a3[] = new BigInteger(str, 16).toByteArray();
byte a[] = new byte[a3.length - 1];
for (int i = 1; i < a3.length; i++)
a[i - 1] = a3[i];
byte a3[]=新的BigInteger(str,16).toByteArray();
字节a[]=新字节[a3.length-1];
对于(int i=1;i
此处a3
包含检索到的字节数据;
a1
包含实际的字节流方法2看起来正确(没有检查所有其他方法)--您的问题可能在其他地方。您确定从XML提取的字符串完整吗?您使用的是哪个解析器?可能它返回多个部分的长字符串(我认为SAX解析器可能就是这种情况),而您只提取第一部分
下面是我将如何实现解码部分(通过子字符串
、大整数
、char[]
等避免不必要的额外分配;但为了提高性能,您可能需要使用BufferedOutputStream):
String photo=“0000005000000050FF191818FF15”;
FileOutputStream fos=新的FileOutputStream(“D:/Images/image6.jpg”);
对于(int i=0;i
嗨,彼得,这也不是working@Nick以何种方式?您是否尝试将生成的字节数组写入文件以进行测试?@Nick,什么意思不工作?它会为我生成预期的结果。是的,我使用FileOutputStram byte[]bytes=new BigInteger(“10”+photo,16)。toByteArray()将字节数组写入文件;FileOutputStream fos=newfileoutputstream(“D://Images/image.jpg”);fos.write(字节);fos.flush();fos.close();您需要删除“伪字节”;例如fos.write(字节,1,字节.长度-1);
这“如何表示jpg文件”?它不是原始JPG,也不是JFIF或BASE64或任何东西。它看起来像是十六进制编码的,但据我所知,JPG不应该以0x00,0x00开头,而是以0xff,0xd8开头。请看Hi@Nick。你成功了吗??
String photo = "0000005000000050FF191818FF15";
FileOutputStream fos = new FileOutputStream("D:/Images/image6.jpg");
for (int i = 0; i < photo.length; i += 2) {
int byte = Character.digit(photo.charAt(i), 16) * 16 +
Character.digit(photo.charAt(i + 1), 16);
fos.write(byte);
}
fos.close();