Search code examples
pythonimage-processingbase64asciiheader-files

Convert image header information to ASCII code


I got a string with image header information like pixel number for each dimension. Here the header: "1 10 10 1 4 LE". In addition to that the other image data is saved in the following base64 code: "+igSKdAm9CVoJhYnzidqKLsmnyX2JwQo9CYhJgMmaCb5Jo0nMSevJmAnwibIJuEmnyZRJpomNicxJ9gmfSeoJkcmySZAJ/Am2CZZJ78nOSeUJ7km+CWVJpMnyCebJ6UnoiclJ7UmPyY3JgsnwyfGJ7cniSdlJ3oneSajJi8n3ye5Jz4nvCeMJ1onYSdAJ3QnsScLKHsnTCfuJ6MnGCdaJ2onECfUJmcnhicEKAko9yZPJjYn0SY7JmkmKid3J1goDyhOJrIldic=".

I tried to combine these two strings to write in a png file by using this code.

import base64
with open("testbild.png", "rb") as img_file:
    imageData = base64.b64encode(img_file.read())
print(imageData)

imageHeader = bytearray("1 10 10 1 4 LE")
print(imageHeader)
imageData = "+igSKdAm9CVoJhYnzidqKLsmnyX2JwQo9CYhJgMmaCb5Jo0nMSevJmAnwibIJuEmnyZRJpomNicxJ9gmfSeoJkcmySZAJ/Am2CZZJ78nOSeUJ7km+CWVJpMnyCebJ6UnoiclJ7UmPyY3JgsnwyfGJ7cniSdlJ3oneSajJi8n3ye5Jz4nvCeMJ1onYSdAJ3QnsScLKHsnTCfuJ6MnGCdaJ2onECfUJmcnhicEKAko9yZPJjYn0SY7JmkmKid3J1goDyhOJrIldic="
# Decode base64 String Data
decodedData = base64.b64decode((imageData))
print(decodedData)
print(len(decodedData))
Image = imageHeader + decodedData
  
# Write Image from Base64 File
imgFile = open('image.png', 'wb')
imgFile.write(Image)
imgFile.close()

My question is how can i use the header inforamtion to add to the ascii code or the base64 so i get the final png file back.


Solution

  • Mmmm, your base64-encoded data once decoded, appears to be 200 bytes long. As the number 10 appears twice in the header, and the string LE I am assuming the data corresponds to a 10x10 pixel image of little-endian uint16, greyscale pixels:

    If so, you can extract it like this:

    from PIL import Image
    import numpy as np
    import base64
    
    # Decode base64
    decodedData = base64.b64decode((imageData))
    
    # Treat as 10x10 array of np.uint16
    im = np.frombuffer(decodedData, dtype=np.uint16).reshape((10,10))
    
    # Contrast-stretch to full scale 0..65535
    scaled = 65535. * (im - im.min())/(im.max() - im.min())
    
    # Make into PIL Image and save
    Image.fromarray(scaled.astype(np.uint16)).save('result.png')
    

    You may or may not want the contrast enhancement I applied to make it visible on StackOverflow. This is the (enlarged) result:

    enter image description here