1

I have an text file called with the extension '.image', at the top of the file is the following:

Image Type: unsigned char
Dimension: 2
Image Size: 512 512
Image Spacing: 1 1
Image Increment: 1 1
Image Axis Labels: "" "" 
Image Intensity Label: ""
193

I believe this to be an unsigned char file, but i'm having a hard time opening it in python (and saving it as a jpg, png etc)

Have tried the standard PIL.Image.open(), saving as a string and reading with Image.fromstring('RGB', (512,512), string), and reading as byte-like object Image.open(io.BytesIO(filepath))

Any ideas? Thanks in advance

6
  • Please share the file, probably using Dropbox, Google Drive or somesuch. Commented Feb 24, 2022 at 15:49
  • @MarkSetchell I'm afraid I cant as it contains confidential data Commented Feb 25, 2022 at 9:54
  • Mmm... not ideal. Ok, what is the size of the file in bytes please? Commented Feb 25, 2022 at 9:57
  • 262.3 kB (262,341 bytes) Commented Feb 25, 2022 at 9:59
  • Ok, if your image is 512x512 pixels, you need 262,4000 bytes plus whatever is in the header so you are missing some pixels. Try changing h to 500 in my code as a quick check. Commented Feb 25, 2022 at 10:02

1 Answer 1

1

If we assume there is some arbitrary, unknown length header on the file, we can read the entire file and then rather than parsing the header, just take the final 512x512 bytes from the tail of the file:

#!/usr/bin/env python3

from PIL import Image
import pathlib

# Slurp the entire contents of the file
f = pathlib.Path('image.raw').read_bytes()

# Specify height and width
h, w = 512, 512

# Take final h*w bytes from the tail of the file and treat as greyscale values, i.e. mode='L'
im = Image.frombuffer('L', (w,h), f[-(h*w):], "raw", 'L', 0, 1)

# Save to disk
im.save('result.png')

Or, if you prefer Numpy to Pathlib:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

# Specify height and width
h, w = 512, 512

# Slurp entire file into Numpy array, take final 512x512 bytes, and reshape to 512x512
na = np.fromfile('image.raw', dtype=np.uint8)[-(h*w):].reshape((h,w))

# Make Numpy array into PIL Image and save
Image.fromarray(na).save('result.png')

Or, if you don't really fancy writing any Python, just use tail in Terminal to slice the last 512x512 bytes off your file and tell ImageMagick to make an 8-bit PNG from the grayscale byte values:

tail -c $((512*512)) image.raw | magick -depth 8 -size 512x512  gray:- result.png
Sign up to request clarification or add additional context in comments.

4 Comments

Mark, very thorough!
@MarkSetchell Thanks for your help, but i got the following errors:ValueError: buffer is not large enough from the first piece of code, and ValueError: cannot reshape array of size 0 into shape (512,512) for the second. Essentially the output is empty (b'' and array([], dtype=uint8)
Scratch my last comment.. One of the .image files was actually empty. The other was 262kb and your code worked perfect. I shall mark your solution as correct :)
Cool - well done. Good luck with your project!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.