leob
leob

Reputation: 141

Opening an image in python and resaving it with the same resolution and dpi

I'm learning some very basic steganography using python.

So far, I've been opening the file using:

from matplotlib import pyplot as plt
import numpy as np

file_location = '...'.png

rgb_data = np.array(plt.imread(file_location))

...
manually or otherwise edit some RGB values
...

plt.axis('off')
plt.imshow(rgb_data)
plt.savefig('image.jpg', dpi=96)

Note: In the above code, I've left out the particular edits I've been doing to the image. This is because I don't think they are part of my issue. Even if I make no changes at all, and just load then resave the image, I still encounter the issues below.

I've encountered three issues trying to save images using matplotlib in this way.

1. Getting the dpi to match I'm not certain how to get the dpi of the output image to automatically match the dpi of the read image.

2. Getting the resolution to match The resolutions of the input and output image by default don't match. Even if I manually match the dpi of the two images, they still don't have matching resolutions.

3. Getting the file sizes to match My end goal is to produce an image that has the same dpi, resolution, and file size as the original. That way, when I start playing around with the RGB values, it should superficially appear to be the exact same image.

My question is how to save the file so the dpi and resolution (and presumably by extension the size...) of the output image match the input?

Of course, the number of pixels in the image, along with the dpi, should fix the resolution. However, it appears as though the output image is saved with a white border surrounding it, which is throwing off the resolution too.

Solutions using any python library are appreciated. However, edits to the existing code are preferable. Since I use matplotlib a lot, it would be useful to know how to circumvent this problem in the future too. Your help would be really appreciated!

Upvotes: 0

Views: 721

Answers (1)

Mikhail Li
Mikhail Li

Reputation: 36

plt.save(...) will save a Matplotlib figure. If you want to use only Matplotlib, please refer this post.

from matplotlib import pyplot as plt
import numpy as np

file_location = '...'.png

rgb_data = np.array(plt.imread(file_location))

# modify your image

fig = plt.figure(frameon=False)

h, w, _ = rgb_data.shape
fig.set_size_inches(w, h)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)

ax.imshow(rgb_data, aspect='auto')

path_to_save = "..."
fig.savefig(path_to_save)

The output image should match the input image.

But I think it will be better to save your image by using pillow.

import PIL.Image as Image
import numpy as np

file_location = "img.png"
path_to_save = "out.png"

img = Image.open(file_location) 
rgb_data = np.array(img)

# modify your image

rgb_data = Image.fromarray(rgb_data)
rgb_data.save(path_to_save, format="PNG") 
# you can also specify dpi, quality and etc.
# for example rgb_data.save(path_to_save, format="PNG", dpi=(300,300))

(Note: it is possible that due to compression settings of the input image size, the output size will be different, refer to this post)

Upvotes: 2

Related Questions