I just “move” image, and its metadata changes…

2019-07-20 15:09发布

问题:

I simply copied my image and saved it to another temp folder in the current directory, nothing is modified, but the image is taking way more "disk space" than it's "bytes size".

And! When I done so, I lost most of my image's metadata such as location data, Device model, F number and others, only Color space, Alpha channel and Dimensions are preserved.

Here is the code I do:

from PIL import Image
import os

image_path = "/Users/moomoochen/Desktop/XXXXX.jpg"
img = Image.open(image_path)
pathname, filename = os.path.split(image_path)

new_pathname = (pathname + "/temp")

if not os.path.exists(new_pathname):
    os.makedirs(new_pathname)
    img.save(os.path.join(new_pathname, filename))

    # If I want to adjust the quality, I do this:
    img.save(os.path.join(new_pathname, filename), quality=80)

So my question is:

1) Why bytes size is different than disk space?

2) How can I adjust my code so that it will preserve all image's metadata?

回答1:

Two things...

You are not actually "simply copying" your file. You are opening it in an image processor, expanding it out to a processable matrix of pixels and then resaving the image to disk - minus anything that your image processor wasn't interested in :-)

If you want to copy the complete file including EXIF data, use shutil like this:

#!/usr/local/bin/python3

from shutil import copyfile
copyfile('source.jpg', 'destination.jpg')

Check in Finder:


Secondly, all "on-disk" filesystems have a minimum allocation unit which means that if your file grows, it will grow by a whole unit, even if you just need 1 more byte of space. Most disks use a 4,096 byte allocation unit, so a 33 byte file will take up 4,096 bytes of space. I must say yours is rather higher than 4k of slack so maybe you are running on a fat RAID that works in big blocks to increase performance?

As an example, you can do this in Terminal:

# Write a file with 1 logical byte
echo -n "1" > file

# Look at file on disk
ls -ls file

8 -rw-r--r--  1 mark  staff  1 15 Nov 08:10 file

Look carefully, the 1 after staff means the logical size is 1 byte and that's what programs get if they read the whole file. But the first 8 on the left is the number of blocks on disk. Each block is 512 bytes, so this 1-byte file takes 8 blocks of 512 bytes, i.e. 4kB on disk!