I'm resizing various images with GAE Image service like this:
from google.appengine.api images
img = images.Image(image_data=get_file_content(image_file_path))
img.resize(width=600)
thumbnail_data = img.execute_transforms(output_encoding=images.JPEG)
It works fine but for an animated GIF image, execute_transforms raises LargeImageError. The image size is 143KB and has a resolution of 607x571px. This happens in GAE but not in my local development server.
In Images Python API Overview says that the image must be no larger than 32 megabytes. But this is not the case.
This looks like a legitimate bug to me. It is possible that the Image service somehow treats all frames in an animated GIF as a single image, exceeding the size limit.
Note that black image is not a bug. JPEG does not support transparency:
transparent_substitution_rgb
If transparent pixels are not supported
in the destination image format, the default is to substitute black.
You can replace this default color with another substitution by
specifying it in 32-bit RGB format.
It is indeed a bug, one of the many images service bugs/shortcomings, I suspect a major improvement to the images service should be on it's way, it has been lagging behind the latest resolution improvements / retina screens etc.
Please star this issue - they fix things when a lot of people star an issue, I've also linked this question over the issue tracker
Related
I have a problem_page such that
from PIL import Image
problem_page = "/home/rajiv/tmp/kd/pss-images/f1-577.jpg"
img = Image.open(problem_page)
results in
PIL.Image.DecompressionBombError: Image size (370390741 pixels) exceeds limit of 178956970 pixels, could be decompression bomb DOS attack.
I'd like to respect the limit and not increase the limit (as described here: Pillow in Python won't let me open image ("exceeds limit"))
How can I load it in a way that the resolution is lowered just below the limit and the lower resolution image is referenced in img without causing any error.
It'd be great to have a Python solution but if not, any other solution will work too.
Update(to answer questions in comments):
These images are derived from PDFs to do machine learning(ML). These PDFs come from outside the system. So we have to protect our system from possible decompression bombs. For most ML, pixel size requirements are well below the limit imposed by PIL so we are ok with that limit as a heuristic to protect us.
Our current option is to use pdf2image which converts pdfs to images and specify a pixel size (e.g. width=1700 pixels, height=2200 pixels) there but I was curious if this can be done at the point of loading an image.
I am using opencv module to read and write the image. here is the code and below is the image i am reading and second image is after saving it on disk using cv2.imwrite().
import cv2
img = cv2.imread('originalImage.jpg')
cv2.imwrite('test.jpg',img)
It is significantly visible that colors are dull in second image. Is there any workaround to this problem or I am missing on some sort of setting parameters..?
I have done a bit of research on the point #mark raised about ICC profile. I have figured out a way to handle this in python PIL module. here is the code that worked for me. I have also learned to use PNG file format rather JPEG to do lossless conversion.
import Image
img = Image.open('originalImage.jpg')
img.save('test.jpg',icc_profile=img.info.get('icc_profile'))
I hope this will help others as well.
The difference is that the initial image (on the left in the diagram) has an attached ICC profile whereas the second one (on the right) does not.
I obtained the above image by running the ImageMagick utility called identify like this:
identify -verbose first.jpg > 1.txt
identify -verbose second.jpg > 2.txt
Then I ran the brilliant opendiff tool (which is part of macOS) like this:
opendiff [12].txt
You can extract the ICC profile from the first image also with ImageMagick like this:
convert first.jpg profile.icc
Your first input image has some icc-Profile associated in the meta-data, which is an optional attribute and most devices may not inject it in the first place. The ICC profile basically performs a sort of color correction, and the correction coefficients are calculated for each unique device during calibration.
Modern Web Browsers, Image Viewing utilities mainly take into account this ICC profile information before rendering the image onto the screen, that is the reason why there is a diff in both the images.
But Unfortunately OpenCV doesn't reads the ICC config from the meta data of the image to perform any color correction.
I've got a pretty strange issue. I have several tif images of astronomical objects. I'm trying to use opencv's python bindings to process them. Upon reading the image file, it appears that segments of the images are swapped or rotated. I've stripped it down to the bare minimum, and it still reproduces:
img = cv2.imread('image.tif', 0)
cv2.imwrite('image_unaltered.tif', img)
I've uploaded some samples to imgur, to show the effect. The images aren't super clear, that's the nature of preprocessed astronomical images, but you can see it:
First set:
http://imgur.com/vXzRQvS
http://imgur.com/wig99KR
Second set:
http://imgur.com/pf7tnPz
http://imgur.com/xGn9C77
The same rotated/swapped images appear if I use cv2.imShow(...) as well, so I believe it's something when I read the file. Furthermore, it persists if I save as jpg as well. Opening the original in Photoshop shows the correct image. I'm using opencv 2.4.10, on Linux Mint 17.1. If it matters, the original tifs were created with FITS liberator on windows.
Any idea what's happening here?
I am currently trying to make a simple image viewers that lets me view images or gifs. I've done most of the work and it's coming out how I'd like it, but I'd also like to be able to view gifs that are too big for my screen. I have a normal 1080p monitor, but the images are 1900x1300, which I understand is an odd image size for gifs. Problem is, pyglet has no obvious way to scale down gifs when drawing them. I'm using sprites, but scaling down the sprite merely returns an error, as the image itself hasn't actually changed, and is still 1900x1300.
What I need is a method to take a gif file, scale it down by 1/2, and render that gif using pyglet. I could probably use other libraries, but I'm trying to keep the project small.
Thanks!
I am using the following code to resize an image using PIL
img = Image.open("in.png")
resized = ImageOps.fit(img, (200, 200), method=Image.ANTIALIAS)
resized.save("out.png")
But the output image colors look very different. Here they are for comparison, the big one is the original:
What's even stranger is that when I open them using the image viewer in ubuntu, they look the same. But not in Windows or MacOS.
The larger image is using the Adobe RGB color profile. It is omitted from the smaller image, which means the color correction system will use some default (probably sRGB), which likely has a smaller gamut. This will cause the colors to appear duller.
Solution 1: Create the original image using sRGB instead of Adobe RGB.
Solution 2: Copy the color profile from the larger image to the smaller image.
Most Linux systems do not support color correction, at least not on the same scope that OS X or Windows do. So the fact that they appear the same in Ubuntu's image viewer is really a limitation of the image viewer program, which is unable to understand color profiles.