I'm not very hopeful that this is actually even possible because JPG is a lossy compression format, but I'll ask anyway.
I have some incomplete metadata about an image, and need to figure out the dimensions without loading the file into memory, or using command-line tools like imagemagick.
This is what I know:
file format is JPG (JPG is an 8-bit image format).
total file size is 96284 bytes.
image width is 600 pixels.
Assuming the height could be variable, is there a mathematical equation I can use to calculate the height predictably?
No, there is no relation between the number of pixels and the compressed size.
You can try your luck by analyzing the file header to get the width/height tags. A library like jpeglib allows you to read just the header, but it takes some effort to integrate it.
I have a question with regard to JPEG file writing. Suppose I have a PNG file example.png, and I want to change the file format to JPEG without any information loss. For the now being, I have two solutions:
Solution 1: perform the file formatting transformation with MATLAB
I = imread('example.png');
imwrite(I,'example.jpg','Mode','lossless');
II = imread('example.jpg');
differ = I-II;
max(differ(:))
This solution can produce lossless JPEG files. However, the problem with this solution is that
some information in the original image such as the DPI resolution may be lost. Moreover, the
produced output image cannot be viewed by popular image viewers such as IrfanView and Windows
Paint.
Solution 2: use IrfanView software.
Use the "Save as" function of IrfanView program, we can change the file format very easily. However, although I have set 'best quality 100' option when saving the JPEG file, the output image also show some information loss. The difference between these two images are not zero for all the pixels.
I am therefore wondering what I should do in order to solve the problem. Any ideas will be appreciated.
This problem has no solution (yet, as of 2018).
You can't avoid use of lossy compression if you want the JPEG file to be usable in majority of image viewers.
The commonly supported version of JPEG is based on DCT compression, which - by definition - performs transformation and rounding that causes some precision loss.
The alternative, lossless JPEG compression method, JPEG-LS, is rarely supported.
There's also JPEG-XT extension that's a combination of lossy image + layer for reconstruction of the lossless original. It fails gracefully in JPEG image viewers, but it's even newer, and I don't know if it's implemented anywhere yet.
If you really need lossless, use PNG. With JPEG the best you can get is minimally lossy JPEG in RGB colorspace at quality=100 (which isn't literally 100%).
I have a small script that I use to resize all of the images in a directory. I run this script in cygwin and it uses "convert" to do the image resizing. The images change their resolution just fine, but I am having problems with file sizes after the script is run.
I typically use this script to resize images dumped out from a Powerpoint presentation to use in a little web presentation app that I wrote. When I dump out gif's and run the script, the files more than double in size (ex. 8KB to 18KB; 14KB to 50KB)
The pertinent lines of the script are as follows:
/usr/bin/convert $holdfile -thumbnail x480 temp.GIF
mv temp.GIF $i
Is there a switch to prevent the file sizes from growing so much? I know that the file sizes are not huge, but when I have a good number of people connecting to a presentation or the unavoidable dialup users, I just want to make their experience as nice as possible.
Edit: I should have specified that the files start at a 960px x 720px resolution and are being resized to 640px x 480px.
Well, this can happen if convert compresses worse than the input files. Since the exact same compression scheme might yield different results depending how good the compressing code is this can happen.
Another, more likely option here would probably be that you are resizing the images which will probably be done with bicubic resizing. This causes the edges of text or drawings to become a little bit blurry. This means they use up more colors and compress worse.
Also likely would be that your original images use an optimized color palette, maybe just with a few colors and after resizing they need the full 256 colors which are supported by a single GIF frame, due to smoothing done by the resizing.
In any case, you probably should see better performance using PNG instead of GIF. PNG was designed as a modern replacement for GIF and no (graphical) browser in use today has problems displaying PNGs (without an alpha channel). PNG compresses much better than GIF, and allows more colors at the same time. Also there are tools like optipng which will compress PNG images even further.
Convert automatically optimizes the palette however the palette might be growing due to colors being blended during resize. You should be able to inspect the source and resultant images in a graphics program and see the number of colors.
GIF only supports LZW compression but due to patent restraints that have since expired (the last was 2004) it was once necessary to manually enable LZW compression. I'm not sure if that is still the case however it's worth looking into.
If LZW compression is specified but
LZW compression has not been enabled,
the image data is written in an
uncompressed LZW format that can be
read by LZW decoders. This may result
in larger-than-expected GIF files.
- imagemagick.org
Consider an application handling uploading of potentially very large PNG files.
All uploaded files must be stored to disk for later retrieval. However, the PNG files can be up to 30 MB in size, but disk storage limitations gives a maximum per file size of 1 MB.
The problem is to take an input PNG of file size up to 30 MB and produce an output PNG of file size below 1 MB.
This operation will obviously be lossy - and reduction in image quality, colors, etc is not a problem. However, one thing that must not be changed is the image dimension. Hence, an input file of dimension 800x600 must produce an output file of dimension 800x600.
The above requirements outlined above are strict and cannot be changed.
Using ImageMagick (or some other open source tool) how would you go about reducing the file size of input PNG-files of size ~30 MB to a maximum of 1 MB per file, without changing image dimensions?
PNG is not a lossy image format, so you would likely need to convert the image into another format-- most likely JPEG. JPEG has a settable "quality" factor-- you could simply keep reducing the quality factor until you got an image that was small enough. All of this can be done without changing the image resolution.
Obviously, depending on the image, the loss of visual quality may be substantial. JPEG does best for "true life" images, such as pictures from cameras. It does not do as well for logos, screen shots, or other images with "sharp" transitions from light to dark. (PNG, on the other hand, has the opposite behavior-- it's best for logos, etc.)
However, at 800x600, it likely will be very easy to get a JPEG down under 1MB. (I would be very surprised to see a 30MB file at those smallish dimensions.) In fact, even uncompressed, the image would only be around 1.4MB:
800 pixels * 600 pixels * 3 Bytes / color = 1,440,000 Bytes = 1.4MB
Therefore, you only need a 1.4:1 compression ratio to get the image down to 1MB. Depending on the type of image, the PNG compression may very well provide that level of compression. If not, JPEG almost certainly could-- JPEG compression ratios on the order of 10:1 are not uncommon. Again, the quality / size of the output will depend on the type of image.
Finally, while I have not used ImageMagick in a little while, I'm almost certain there are options to re-compress an image using a specific quality factor. Read through the docs, and start experimenting!
EDIT: Looks like it should, indeed, be pretty easy with ImageMagick. From the docs:
$magick> convert input.png -quality 75 output.jpg
Just keep playing with the quality value until you get a suitable output.
Your example is troublesome because a 30MB image at 800x600 resolution is storing 500 bits per pixel. Clearly wildly unrealistic. Please give us real numbers.
Meanwhile, the "cheap and cheerful" approach I would try would be as follows: scale the image down by a factor of 6, then scale it back up by a factor of 6, then run it through PNG compression. If you get lucky, you'll reduce image size by a factor of 36. If you get unlucky the savings will be more like 6.
pngtopng big.png | pnmscale -reduce 6 | pnmscale 6 | pnmtopng > big.png
If that's not enough you can toss a ppmquant in the middle (on the small image) to reduce the number of colors. (The examples are netpbm/pbmplus, which I have always found easier to understand than ImageMagick.)
To know whether such a solution is reasonable, we have to know the true numbers of your problem.
Also, if you are really going to throw away the information permanently, you are almost certainly better off using JPEG compression, which is designed to lose information reasonably gracefully. Is there some reason JPEG is not appropriate for your application?
Since the size of an image file is directly related to the image dimensions and the number of colours, you seem to have only one choice: reduce the number of colours.
And ~30MB down to 1MB is a very large reduction.
It would be difficult to achieve this ratio with a conversion to monochrome.
It depends a lot on what you want at the end, I often like to reduce the number of colors while perserving the size. In many many cases the reduced colors does not matter. Here is an example of reducing the colors to 254.
convert -colors 254 in.png out.png
You can try the pngquant utility. It is very simple to install and to use. And it can compress your PNGs a lot without visible quality loss.
Once you install it try something like this:
pngquant yourfile.png
pngquant --quality=0-70 yourfile.png
For my demo image (generated by imagemagick) the first command reduces 350KB to 110KB, and the second one reduces it to 65KB.
Step 1: Decrease the image to 1/16 of its original size.
Step 2: Decrease the amount of colors.
Step 3: Increase the size of the image back to its original size.
I know you want to preserve the pixel size, but can you reduce the pixel size and adjust the DPI stored with the image so that the display size is preserved? It depends on what client you'll be using to view the images, but most should observe it. If you are using the images on the web, then you can just set the pixel size of the <img> tag.
It depends on they type of image, is it a real life picture or computer generated image,
for real life images png will do very little it might even not compress at all, use jpg for those images, it the image has a limited number of different colors (it can have a 24 bit image depth but the number of unique images will be low) png can compress quite nicely.
png is basicly an implementation of zip for images so if a lot of pixels are the same you can have a rather nice compression ratio, if you need lossless compression don't do resizing.
use optipng it reduce size without loss
http://optipng.sourceforge.net/
Try ImageOptim https://imageoptim.com/mac it is free and open source
If you want to modify the image size in ubuntu, you can try "gimp".
I have tried couple of image editing apps in ubuntu and this seemed to be the best among them.
Installation:
Open terminal
Type: sudo apt install gimp-plugin-registry
Give admin password. You'll need net connection for this.
Once installed, open the image with GIMP image editor. Then go to: File > Export as > Click on 'Export' button
You will get a small window, where check box on "Show preview in image window". Once you check this option, you will get to see the current size of the file along with Quality level.
Adjust the quality level to increase/decrease the file size.
Once adjusting is done, click on 'Export' button finally to save the file.
Right click on the image. Select open with paint. Click on resize. Click on pixel and change the horizontal to 250 or 200.
That's the only thing. It is the fastest way for those who are using Windows XP or Windows 7.
I'd like to save an existing image as a PNG or JPG at a given file size, eg, 100KB.
PNG uses lossless compression so you can not compress it below a certain level.
In .NET you can save a JPG with compression, and guess how big the file will be when completed.
http://msdn.microsoft.com/en-us/library/system.drawing.image.save(VS.80).aspx
- See the "Save JPEG image with compression value" section.
Also, you could resize the image dimensions to make it smaller.
Only if using JPG 2000 you could set the file size to a specific value. Using JPG, you'll have to try different quality values and using PNG will get you one size for a given image and a compression level - you can only try to resize the image which will give you a smaller size.
You could also try to resize the image so that an uncompressed image would have the size you want, but then PNG and especially JPG will often have a much lower file size.
For PNG there isn't really a quality setting, so you can't really control the file size.
Jpg has a quality setting that determines how good a quality the image will be. lower quality settings result in smaller files. However, there is normally no option for "give the quality needed for a file of size x".
You can achieve the same result using a rather inefficient approach of converting to jpg in memory, seeing how big the output is, adjusting the quality up or down and repeating until you get close enough. It might sound terrible, but if your images aren't too big you may find no one notices the short delay while you do this.