Convert hexadecimal string to image file

I have a requirement to read a Hex String with leading zeros that represent a JPEG file from the resulting XML file and save it as an image file. Image data looks like

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

In the xml file, the line Length between the tag is 51216. I read the Hex data between the Photo tag as a String and converted it to byte [], and using FileOutputStream , I write to the file, but when I try to open the image file, it says: "The file is damaged , corrupted or file too large. " I tried many ways to save the image, but did not succeed. I list the methods used below. Please help me with 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(); 
+4
source share
4 answers

The shortest way could be this.

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

prints

[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]

0
source
 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(); } } } 
0
source

When you extract the file, the space will be added at the beginning of the hexadecimal string, so remove the space and save it in another byte array, and it works fine:

here is the code to remove the starting space

 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]; 

Here a3 contains the extracted byte data;
a1 contains the actual byte stream

0
source

Method 2 looks right (didn't check everyone else) - your problem is probably in a different place. Are you sure the string extracted from XML is complete? Which parser are you using? Perhaps it returns long strings in several parts (I think this may be the case for SAX parsers), and you only extract the first part?

Here's how I could implement the decoding part (avoiding unnecessary extra allocations via substring , BigInteger , char[] , etc ...., for performance you can use 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(); 
0
source

Source: https://habr.com/ru/post/1387867/


All Articles