Python 'Out of memory' when opening image - python

import pygame
from pygame.locals import * \
image = pygame.image.load('.\\w.jpg')
I'm trying to load an 59MB jpg file and it fails saying 'Out of memory'
I'm using windows 64bit and python 3.10.4 64bit.
My computer had more than 10GB of free ram left when the program ran.

As seen in the Wikipedia entry for JPEG, JPEG is a method of compression for digital images. So even if your jpg file is only 59MB the uncompressed image could take much more than that, depending on the amount of redundancy in the original image. The Wikipedia article asserts that JPEG typically achieves 10:1 compression and at first one might think, based on this assertion about typical compression rates, that even in uncompressed form that the image would not be too large. However, JPEG also uses Huffman coding and the amount of compression in Huffman coding can be extremely high if the uncompressed data is sufficiently redundant.

Related

Compression PNG with PIL and cv2

Im trying to make image compressor in my django project. I did well with jpg, but got a lot of problems with png. For compression i using PIL and cv2, but cant get result better then 16% of compression for big PNG files (>1 mb). Ive tryed to combine both libraries, and its still not innove. Here simple code of my view:
(the above code for jpg compression)
elif picture.mode == ('RGBA'):
if photo.image.size < 1000000:
colorsloss = picture.convert(mode="P", palette=Image.ADAPTIVE)
colorsloss.save('media/new/'+name,"PNG",quality=75, optimize=True, bits=8)
else:
originalImage = cv.imread(str('/home/andrey/sjimalka'+ photo.image.url))
cv.imwrite('media/new/'+name, originalImage,[cv.IMWRITE_PNG_COMPRESSION, 9])
cvcompressed = Image.open('media/new/'+name)
cvcompressed.convert(mode="RGB")
cvcompressed.save('media/new/'+name,"PNG",quality=75, optimize=True)
So here ive got 2 big problems:
1) If ive got low size image (< 1 mb), i using P mode in Pillow. It works great, but if i compressing image with gradient, i can see some distortions in places where i got gradient.
I have good compression (something like 85%), but no idea yet how to fix it.
2) I cant get good compression of big png files. My best goal yet is 16%, with really good quality, but it still not innove. Mb i do something wrong, or i shold use any other library or technology to make it better. I want to get a list 50% of compression with big png files.
I already tryed to use pngquant, but their docs wasnt too clear for me, and i cant find good code examples.
PNG is lossless. You cannot choose to discard information when writing in order to make files smaller like you can with JPEG.
If you go for a palettised version, you only need one byte per pixel instead of three, but then you only get 256 colours and gradients will look rubbish.
Also, the quality setting is not the same as for JPEG - it is more like the --fast or --best parameter to gzip.
One thing you can do, if you have large areas of transparency like you do, is make black all pixels that are 100% transparent. That will help them compress better. See example here.

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/

Why the frames of a VideoClip change when it is written to a video file?

I wrote the following code:
from moviepy.editor import *
from PIL import Image
clip= VideoFileClip("video.mp4")
video= CompositeVideoClip([clip])
video.write_videofile("video_new.mp4",fps=clip.fps)
then to check whether the frames have changed or not and if changed, which function changed them, i retrieved the first frame of 'clip', 'video' and 'video_new.mp4' and compared them:
clip1= VideoFileClip("video_new.mp4")
img1= clip.get_frame(0)
img2= video.get_frame(0)
img3= clip1.get_frame(0)
a=img1[0,0,0]
b=img2[0,0,0]
c=img3[0,0,0]
I found that a=24, b=24, but c=26....infact on running a array compare loop i found that 'img1' and 'img2' were identical but 'img3' was different.
I suspect that the function video.write_videofile is responsible for the change in array. But i dont know why...Can anybody explain this to me and also suggest a way to write clips without changing their frames?
PS: i read the docs of 'VideoFileClip', 'FFMPEG_VideoWriter', 'FFMPEG_VideoReader' but could not find anything useful...I need to read the exact frame as it was before writing in a code I'm working on. Please, suggest me a way.
Like JPEG, MPEG-4 uses lossy compression, so it's not surprising that the frames read from "video_new.mp4" are not perfectly identical to those in "video.mp4". And as well as the variations caused purely by the lossy compression there are also variations that arise due to the wide variety of encoding options that can be used by programs that write MPEG data.
If you really need to be able to read back the exact same frame data that you write then you will have to use a different file format, but be warned: your files will be huge!
The choice of video format partly depends on what the image data is like and on what you want to do with it. If the data uses 256 colours or less, and you don't intend to perform transformations on it that will modify the colours, a simple GIF anim is a good choice. But bear in mind that even something like non-integer scaling modifies colours.
If you want to analyze the image data and transform it in various ways, it makes sense to use a format with better colour support than GIF, eg a stream of PNG images, which I assume is what Zulko mentions in his answer. FWIW, there's an anim format related to PNG called MNG, but it is not well supported or widely known.
Another option is to use a stream of PPM images, or maybe even a stream of YUV data, which is useful for certain kinds of analysis and convenient if you do intend to encode as MPEG for final consumption. The PPM format is very simple and easy to work with; YUV is slightly messy since it's a raw format with no header data, so you have to keep track of the image size and resolution data yourself.
The file size of PPM or YUV streams is large, since they incorporate no compression at all, but of course they can be compressed using standard compression techniques, if you want to save a little space when saving them to disk. OTOH, typical video processing workflows that use such streams often don't bother writing them to disk: they are sent in pipelines (perhaps using named pipes), so the file size is (mostly) irrelevant.
Although such formats take up a lot of space compared to MPEG-based files, they are far superior for use as intermediate formats while performing image data analysis and transformation, since every time you write & read back MPEG you are losing a little bit of quality.
I assume that you intend to do your image data analysis and transformations using PIL/Pillow. But you can also work with PPM & YUV streams using the ffmpeg / avconv command line programs; and the ffmpeg family happily work with sets of individual image files and GIF anims, too.
You can have lossless compression with the 'png' codec:
clip.write_videoclip('clip_new.avi', codec='png')
EDIT #PM 2Ring: when you write the line above, it makes a video that is compressed using the png algortihm (I'm not sure whether each frame is a png or if it's more subtle).

Compress Images in Python (No Archive)

I'm writing a Python script that deals with images. Is there a module that can compress an image without putting it into an archive, and decompress it back? (e.g. A 1MB image is now 0.8MB after compression, then 1MB after decompression).
Can I see example code of compressing and decompressing an image in Python without the use of archives?
I've already taken a look at some modules, but those compress strings.
You probably want to take a look at the Python Image Library (PIL), and the PNG and JPEG formats.
The PIL Image.save() method will let you save PNG or JPEG images.
PNG - Lossless, good for "cartoony"/logo images with solid colors or small numbers of colors.
JPEG - Lossy, good for photos, images with lots "going on".
Modern image formats such PNG and JPEG are already compressed and my general recommendation is take Brendan Long's advice and use those formats and exploit all the work that's been put into them.
That said, if you want to compress the contents of any arbitrary file in Python, here's a very simple example:
import zlib
with open("MyImage.jpg", "rb") as in_file:
compressed = zlib.compress(in_file.read(), 9)
with open("MyCompressedFile", "wb") as out_file:
out_file.write(compressed)

Video editing with python or command line

I need to perform the following operations in my python+django project:
joining videos with same size and bitrate
joining videos and images (for the image manipulation I'll use PIL: writing text to an existing image)
fading in the transitions between videos
I already know of some video editing libraries for python: MLT framework (too complex for my needs), pygame and pymedia (don't include all the features I want), gstreamer bindings (terrible documentation).
I could also do all the work from command line, using ffmpeg, mencoder or transcode.
What's the best approach to do such a thing on a Linux machine.
EDIT: eventually I've chosen to work with melt (mlt's command line)
http://avisynth.org/mediawiki/Main_Page is a scripting language for video.
Because ffmpeg is available on GNU/Linux, i thing using it with modules such as pexpect or subprocess is the best solution....
You can use OpenCV for joining videos and images. See the documentation, in particular the image/video I/O functions.
However, I'm not sure if the library has functions that will do the fading for you.
What codec are you using?
There are two ways to compress video: lossy and lossless. It's easy to tell them apart. Depending on their length, lossy video files are in the megabyte range, lossless (including uncompressed) are in the gigabyte range.
Here's an oversimplification. Editing video files is a lot different from editing film, where you just glue the pieces of film together. It's not just about bitrate, frame rate and resolution. Most lossy video codecs (MPEG 1-4, Ogg Theora, H.26x, VC-1, etc.) start out with a full frame then record only the changes in movement. When you watch the video what you're actually seeing is a static scene with layer after layer of changes pasted on top of it. It looks like you're seeing full frame after full frame, but if you looked at the data in the file all you'd see would be a black background and scrambled blocks of video.
If it's uncompressed or uses a lossless codec (HuffYUV, Lagarith, FFV1, etc.) then you can edit your video file just like film. You still have to re-encode the video but it won't effect video quality and you can cut, copy and paste however you like as long as the resolution and frame rate are the same. If you're video is lossy you have to re-encode it with some loss of video quality, just like saving the same image in JPEG, over and over.
Another option might be to put several pieces of video into a container like MKV and use chapters to have it jump from piece to piece. I seem to remember being told this is possible but I've never tried it so maybe it isn't.

Categories

Resources