Reducing the file size of a very large images, without changing the image dimensions

94,859

Solution 1

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.

Solution 2

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?

Solution 3

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.

Solution 4

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

Solution 5

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.

Share:
94,859
knorv
Author by

knorv

Updated on July 09, 2022

Comments

  • knorv
    knorv almost 2 years

    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?

  • Eric Pi
    Eric Pi over 14 years
    Aaah... just re-read your initial question. The 800x600 was just an example size. (My mistake.) Nonetheless, the rest of my post should still be valid-- iteratively reduce the quality until the output file is small enough.
  • knorv
    knorv over 14 years
    800x600 was just an example. The dimensions differ from file to file.
  • Norman Ramsey
    Norman Ramsey over 14 years
    @knorv: Indeed. If you could put one of your files in a place we could find it, that might help.
  • Matt Warren
    Matt Warren about 14 years
    Just to add you may need to perform the steps above per image. The quality level of png doesn't guarantee a file size. For instance a blank image and an image of some tress, compressed at the same quality level will have very different file sizes. The file size is dependant on the contents of the image/
  • Sérgio
    Sérgio over 11 years
    Hi , I vote up because is a way to reduce the size of the image. I'd like to know what an image is storing in bits per pixel and reduce the image to a reasonable bits per pixel fixed. So if I got a strong image with bits per pixel I will reduce more than one that not have so many bits per pixel . Thanks
  • Kornel
    Kornel about 11 years
    That's best what you can do with ImageMagick, but pngquant --quality=0-80 in.png will likely give smaller file size.
  • Autonomous
    Autonomous about 10 years
    The OP doesn't want to resize the image, isn't that the case?
  • Vlasec
    Vlasec over 8 years
    You can do some lossy conversion (reducing color depth, changing to indexed etc.) on PNG, too, it is just not a part of the format itself. E.g., there is a tool called TinyPNG (it is not free though) that can greatly shrink the image while it only marginally reduces its quality.
  • jogo
    jogo over 8 years
    gimp uses the same libraries for that as ImageMagick
  • Waleed Abdalmajeed
    Waleed Abdalmajeed almost 6 years
    Solve my issues from the first 6 words.