python imageio image size without loading image to memory - python

I am using imageio with Python. It seems to have a cleaner API than PIL and consorts, so I would like to continue using imageio instead of other tools.
I know how to get image size:
height, width, channels = imageio.imread(filepath).shape
Is there a way to get the size of an image, without needing to load it fully to memory? This should be possible, isnt't it? At least for a number of formats that (I guess) have the image size in the header?

Related

Reading in RAW image is larger

When I read in a camera raw image (CR2) via rawpy it is larger then the original and was wondering if anyone knows what the issue might be. The original image is of size 6000 by 4000, but comes in as 6022 by 4020.
with rawpy.imread(raw_image) as raw:
img = raw.postprocess(output_bps=16, output_color=rawpy.ColorSpace.sRGB)
print(img.shape) # -> (6022, 4020, 3)
Try reading it with scikit-image. If the shape is the same as with rawpy, then it might be due to the extra pixels mentioned by Mark Ransom. If the shape is correct, then the extra pixels were due to the camera sensor and you can now use the image as a numpy array (or try reading it via the rawpy library).
Last but not least, you could try opencv, which can read camera images in real time.
Scikit-image
https://scikit-image.org/

How can I insert EXIF/other metadata into a JPEG stored in a memory buffer?

I have created a JPEG using Python OpenCV, EXIF data being lost in the process and apparently not being able to be re-added when calling imwrite (reference: Can't keep image exif data when editing it with opencv in python).
Two questions:
In general, how can I write the original EXIF data/new custom metadata into a JPEG that exists in memory rather than a file?
Would pillow/PIL be able to maintain the EXIF data and allow supplementary metadata to be added? As of 2013 (reference: how maintain exif data of images resizes using PIL) this did not seem possible except via a tmp file (which is not an option for me).
Thanks as ever
I'm not certain I understand what you are trying to do, but I think you are trying to process an image with OpenCV and then re-insert the EXIF data you lost when OpenCV opened it...
So, hopefully you can do what you are already doing, but also open the image with PIL/Pillow and extract the EXIF data and then write it into the image processed by OpenCV.
from PIL import Image
import io
# Read your image with EXIF data using PIL/Pillow
imWithEXIF = Image.open('image.jpg')
You will now have a dict with the EXIF info in:
imWIthEXIF.info['exif']
You now want to write that EXIF data into your image you processed with OpenCV, so:
# Make memory buffer for JPEG-encoded image
buffer = io.BytesIO()
# Convert OpenCV image onto PIL Image
OpenCVImageAsPIL = Image.fromarray(OpenCVImage)
# Encode newly-created image into memory as JPEG along with EXIF from other image
OpenCVImageAsPIL.save(buffer, format='JPEG', exif=imWIthEXIF.info['exif'])
Beware... I am assuming in the code above, that OpenCVImage is a Numpy array and that you have called cvtColor(cv2.COLOR_BGR2RGB) to go to the conventional RGB channel ordering that PIL uses rather than OpenCV's BGR channel ordering.
Keywords: Python, OpenCV, PIL, Pillow, EXIF, preserve, insert, copy, transfer, image, image processing, image-processing, dict, BytesIO, memory, in-memory, buffer.

the pillow make the image being more size than before

I use python pillow to do a easy gif image reverse,but I found that the image has become more size(10m) than before(1m). Anyone know how to make it?
And here is my code:
from PIL import Image, ImageSequence
from PIL import ImagePalette
with Image.open('sd.gif') as im:
if im.is_animated:
frames = [f.copy() for f in ImageSequence.Iterator(im)]
frames.reverse()
frames[0].save('out.gif', save_all=True, append_images = frames[1:])
I can't tell for sure without examining the actual images, but I can guess what likely happened:
Some gifs are optimized with a method that finds pixels in each frame where nothing is changing (or changing only very slightly) from frame to frame, and make them transparent instead of storing the color for each pixel, to reduce the amount of data. For some gifs with large static areas in many consecutive frames this can be very efficient way to reduce file size.
When you are reversing the GIF, the frames must be unoptimized first, otherwise there would be transparent areas without any data. This can increase file size quite a bit. The difference may vary from one image to another.
You probably can solve this by running some gif optimization algorithm after the new image is created.

Python Pillow lowering image quality doesnt change file size

I am trying to lower the file size of an image using pillow (pil) however lowering the image quality doesn't lower the size of the saves image.
The saved images 'image2' and 'image3' are the same size.
import PIL from Image
im = Image.open('image.png')
im.save('image2.png', quality=100)
im.save('image3.png', quality=10)
The PNG format only supports lossless compression, for which the compression ratio is usually limited and not freely adjustable.
If I am right, there is a variable parameter that tells the compressor to spend more or less time finding a better compression scheme. But without a guarantee to succeed.
You have to use image compression to reduce sizes - pngquant or similar
https://pngquant.org/

Resize GIF animation, pil/imagemagick, python

I want to change size of GIF animation image using python and PIL or PythonMagick. I can't find solution. PIL and thumbnail method works for jpg and png but not for gif. ImageMagick has command mogrify/convert -resize '1280x1024>' but i can't find documentation and i don't know how to do it with pythonmagick.
Anyone knows solution?
In the worst case i use os/subprocess and convert ;-S
Thanks.
You can use PIL and images2gif, a short PIL based module linked to on this blog page, and available here. Code used to process this rose.gif is below. I set the images2gif.readGif 'read as numpy array' property to false in order to get a list of PIL images so as I could use the PIL thumbnail function.
Orignial: Processed:
import Image
import images2gif
frames = images2gif.readGif("rose.gif",False)
for frame in frames:
frame.thumbnail((100,100), Image.ANTIALIAS)
images2gif.writeGif('rose99.gif', frames)
I'm not sure how to preserve transparency, my attempts to do so have failed (so far).
Some amazing person made an updated version of images2gif.py that accounts for transparency:
https://bitbucket.org/bench/images2gif.py/overview
There are still some artifacts, but it's way better than the original!

Categories

Resources