将十六进制字符串转换为图像文件 [英] Converting a Hex String to an image file

查看:77
本文介绍了将十六进制字符串转换为图像文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从接收到的xml文件中读取一个前导零(代表JPEG文件)的十六进制字符串,并将其另存为图像文件.图像数据看起来像

I have a requirement to read a Hex String with leading zeros which represents a JPEG file, from an xml file received and save it as an image file. The image data looks like

0000005000000050FF191818FF151715FF111413FF0E1...........................FF2A2322FF292221

在xml文件中,标签之间的字符串长度为51216,我读取Photo标签之间的十六进制数据作为字符串并将其转换为字节[],并使用 FileOutputStream 正在写入文件.但是,当我尝试打开图像文件时,提示文件似乎已损坏,损坏或文件太大",我尝试了许多方法来保存图像,但未成功.我在下面列出了使用的方法.请帮助我.

In xml file The length of String between the tag is 51216 I read the Hex data in between the Photo tag as a String and Converted it to a byte[], and the using a FileOutputStream I am writing to a file. But when I try to open the image file it tells "the file appears to be damaged,corrupted or file is too large" I have tried many methods to save the image, but no success. I am listing the methods used below. Please help me out from this.

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();

推荐答案

方法2看起来正确(尚未检查所有其他方法)-您的问题可能在其他地方.您确定从XML提取的字符串是完整的吗?您正在使用哪个解析器?也许它会分多个部分返回长字符串(我认为SAX解析器可能是这种情况),而您只提取了第一部分?

Method 2 looks correct (haven't checked all others) -- your problem is probably elsewhere. Are you sure the string extracted from the XML is complete? Which parser are you using? Perhaps it returns long strings in multiple parts (I think this might be the case for SAX parsers), and you are extracting only the first part?

这是我实现解码部分的方式(避免通过 substring BigInteger char [] 等不必要的额外分配...;为了提高性能,您可能需要使用BufferedOutputStream):

Here is how I would implement the decoding part (avoiding unneeded extra allocations via substring, BigInteger, char[] etc...; for performance, you may want to use a BufferedOutputStream though):

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();

这篇关于将十六进制字符串转换为图像文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆