I have read that for reading a compressed image into memory it must be decompressed first and the original size will be allocated. So, since it is decompressed and it's size before compression is allocated in memory, why is the resolution of a compressed image when viewed with a certain software not the same of the original one?
Compression is not about reducing the resolution, or size in pixels, of an image. Compression is about reducing the amount of bytes required to represent a specific image.
You can see an image as an array of 4-byte structures, one for each pixel, where each byte represents one of the components of the color of each pixel, namely red, green, blue and alpha. The size required to represent an image with this scheme is
width * height * 4
So a 100x100 pixel image would have 10000 pixels, and therefore consume 40000 bytes. This is in fact, roughly the way in which the BMP format stores images.
However, this is not the only way you can represent those 10000 pixels. If, for example, the first 5000 pixels are blue, and the bottom pixels are brown, you could represent the image by saying something like "blue: 5000, brown 5000", and that would take much fewer bytes to represent. This scheme is roughly how RLE (Run Length Encoding) works, and is widely used in many formats such as GIF.
However, there is only so much you can do to reduce the amount of bytes required to represent the bytes in your image. The data is not always easy to represent with fewer bytes, so what some compression algorithms, like the one used in JPEG files do, is to modify the pixels just a bit, so the data is much easier to compress, yet the changes are not very noticeable. If such changes are acceptable, it is possible to achieve impressive results when compressing the image. This is what is called "lossy compression".
The entire point of compressing images is to make it easier to move images from one place to another, be it by storing them on a disc or sending them over the internet. However, when you are going to display an image, your computer has to tell the monitor what color each pixel has to get, so once you are going to display the image, you need to decompress it.
Technically, decompressing a compressed image does maintain the quality of the compressed image. However compressing an image may reduce quality (ie. the compressed image is slightly degraded from the original image).
The specific changes to the image depend on what sort of compression you apply; that said, I'm not familiar with any sort of compression that would change the resolution or size of the image. Are you sure you got that right?
Related
I just tried to convert few JPEGs to a GIF image using some online services. For a collection of 1.8 MB of randomly selected JPEGs, the resultant GIF was about 3.8 MB in size (without any extra compression enabled).
I understand GIF is lossless compression. And that's why I expected the resultant output to be around 1.8 MB (input size). Can someone please help me understand what's happening with this extra space ?
Additionally, is there a better way to bundle a set of images which are similar to each other (for transmission) ?
JPEG is a lossy compressed file, but still it is compressed. When it uncompresses into raw pixel data and then recompressed into GIF, it is logical to get that bigger a size
GIF is worse as a compression method for photographs, it is suited for flat colored drawings mostly. It uses RLE [run-length encoding] if I remember well, that is you get entries in the compressed file that mean "repeat this value N times", so you need to have lots of same colored pixels in horizontal sequence to get good compression.
If you have images that are similar to each other, maybe you should consider packing them as consequtive frames (the more similar should be closer) of a video stream and use some lossless compressor (or even risk it with a lossy one) for video, but maybe this is an overkill.
If you have a color image, multiply the width x height x 3. That is the normal size of the uncompressed image data.
GIF and JPEG are two difference methods for compressing that data. GIF uses the LZW method of compression. In that method the encoder creates a dictionary of previously encountered data sequences. The encoder write codes representing sequences rather than the actual data. This can actual result in an file larger than the actual image data if the encode cannot find such sequences.
These GIF sequences are more likely to occur in drawing where the same colors are used, rather than in photographic images where the color varies subtly through out.
JPEG uses a series of compression steps. These have the drawback that you might not get out exactly what you put in. The first of these is conversion from RGB to YCbCr. There is not a 1-to-1 mapping between these colorspaces so modification can occur there.
Next is subsampling.The reason for going to YCbCr is that you can sample the Cb and Cr components at a lower rate than the Y component and still get good representation of the original image. If you do 1 Y to 4 Cb and 4 Cr you reduce the amount of data to compress by half.
Next is the discrete cosine transform. This is a real number calculation performed on integers. That can produce rounding errors.
Next is quantization. In this step less significant values from the DCT are discarded (less data to compress). It also introduces errors from integer division.
I'm very interested in understanding how graphic file format (PNG, JPG, GIF) work. Are there any code examples that demonstrate how these files are made and also how they are interpreted (viewed in browser)?
Regardless of which graphic file format you are working with, you need to understand the basic nature that all graphic files have in common.
File Header
File Type, Version, (Time & Date Stamp - if included)
Possible data structure/s info or chunks
Flags for which color type to be expected, if compression is available and which type, byte order (endian), has transparency, and other various flags.
Image Data Info
Width normally in pixels sometimes in pels, bits or bytes
Height normally in pixels sometimes in pels, bits or bytes
Bits Per Pixel or Pixel Depth
Image Size in Bytes: numPixelsWidth * numPixelsHeight * ((bits or bytes) for each pixel)
Color Type: - Each Pixel has color data which can vary
Gray Scale
Palette
Color RGB
Color RGBA
Possible Others
If Compression Is Present Which Coding and Encoding Is Used
The actual image data
Once you understand this basic structure then parsing image files becomes easier once you know the specification to the file structure you are working with. When you know how many bytes to read in to your file pointer that includes all headers and chunks, then you can advance your file pointer to the data structure that will read in or write out all the pixel (color) data. In many cases the pixel data is usually 24bits per pixel such that each channel RGBA - Red, Green, Blue, and Alpha are 8bits each or one byte same as an unsigned char. This is represented in either a structure or a two dimensional array. Either way once you know the file's structure and know how to read in the actual image or color data you can easily store it into a single array. Then what you do with it from there depends on your application's needs.
The most detailed information can be obtained by reading the file format specification and implementing a parser in the language you know best.
A good way would be to read the format and transform it into an array of four byte tupples (RGBA, the red, green, blue and alpha parts of a color) This will allow you to use this format as an in between format between formats for easy conversion. At the same time most APIs support the displaying of this raw format.
A good format to get started with is BMP. As old as it is, if this is your first encounter with writing a parser this is a safe an 'easy' format. A good second format is PNG. Start with the uncompressed variations and later add the compression.
Next step is TGA to learn reading chunks or JPG to learn more about compression.
Extra tip: Some implementations of writers contain(ed) errors causing images to be in violation of the format. Others added extra features that never made it to the official specs. When writing a parser this can be a real pain. When you are running into problems always second guess the image you are trying to read. A good binary/hex file reader/editor can be a very helpful tool. I used AXE, if I remember correctly it allows you to overlay the hex codes with a format so you can quickly recognize the header and chunks.
I wish to exploit redundancy among a set of similar colored JPG images. Set redundancy compression has been used successfully for similar 8-bit grayscale images. They basically find the MAX and MIN of a set of images and encode the original images as differences with respect to either the MAX or MIN image, depending on whichever is the smaller difference. About 20-50% additional compression has been obtained for grayscale images using this approach besides normal compression tools like gzip or bzip. I do the following:
Decompress the JPG images to RGB char buffers
Compute the MIN and MAX char buffers
Encode the difference char buffers as JPG images
The problem is that to retrieve the original image from the difference image, ideally I would need to encode the difference losslessly. But, there is no lossless transformation from RGB->JPG in libjpeg and even at quality=1.0, because the difference coefficients are small (1~10), I end up losing almost all the information (almost all decoded data is 1~3).
To solve this, I tried using huffman encoding of the difference char buffers.
Encode the difference char buffers using Huffman encoding
The original JPG images are of size ~256 KB, the corresponding RGB buffer is ~7.8 MB and the huffman encoded difference images are of size ~2.2 MB. So, Huffman encoding does save lot of space w.r.t RGB buffers but the original JPG equivalents are much smaller.
Any suggestions to store these difference buffers efficiently comparable in size to the 256 KB original JPG files ?
Is there a way to save these difference buffers with low valued data coefficients as JPG images without losing substantial information ?
I'm going to let users upload images of 300x300 compressed with JPEG. Is there a way to determine what the maximum file size of such an image would be?
I can imagine this can be tried by compressing random noise at 100 quality, but is there a theoretical maximum?
Say that the image is totally uncompressable random noise, could it be 3 bytes per pixel (24-bits colour) and a margin for the metadata? Or could such an image turn out larger than the original when compressed?
From wikipedia:
For highest quality images (Q=100), about 8.25 bits per color pixel is required
http://en.wikipedia.org/wiki/JPEG#Sample_photographs
So, for Q=100 on an 300x300 image, that would result in (300 * 300) px * 8.25 bits/px = 742,500 bits = ~ 93 kB
There are also lossless JPEG coding modes, which are practically not used (last sentence, second paragraph). But they would have the RGB typical 24 bits/pixel.
There is no limit on jpeg metadata size, which means there's no limit to the size of a jpeg file. See this answer I've linked for an explanation of why and also for an example of a realistic situation where the metadata might get large: What is the maximum size of JPEG metadata?
So if assuming a maximum practical/realistic size suits your purpose, then you should factor that example into your calculations. In many contexts it would be fine to just reject things outside of that maximum as outside the domain of your program's intended usage.
But if you absolutely must rely on theoretical, then unfortunately it's a big bold ∞
Note: I do not have a huge amount of personal experience with the jpeg specification, so I am going off of what people have said about repeated fields being allowed, as well as multiple comment fields. Please correct me if you find evidence to the contrary.
I have a 2MB JPEG image, and when I use the option Image > Mode > Convert to colour Profile, the size get reduced to 50KB without to much quality loss.
Could somebody explain why is the size so reduced? Am I missing some important point?
When you reduce the number of colors within an area you reduce the amount of math needed to describe that area, which results in a smaller file size.
I observed the same long time ago while converting JPG images with Image Magic.
JPEG contains information for reproduction of color components on different media. "convert to color profile" reduces this information by choosing concrete profile. This do not degrade quality. More info at ICC