Giter VIP home page Giter VIP logo

imgmin's Introduction

imgmin

Get Started!

sudo apt-get install -y autoconf libmagickwand-dev pngnq pngcrush pngquant
git clone https://github.com/rflynn/imgmin.git
cd imgmin
autoreconf -fi
./configure
make
sudo make install
imgmin original.jpg optimized.jpg

Summary

Image files constitute a majority of static web traffic.[17] Unlike text-based web file formats, binary image files do not benefit from built-in webserver-based HTTP gzip compression. imgmin offers an automated means for enforcing image quality as a standalone tool and as a webserver module. imgmin determines the optimal balance of image quality and filesize, often greatly reducing image size while retaining quality for casual use, which translates into more efficient use of storage and network bandwidth, which saves money and improves user experience.

The Problem

Websites are composed of several standard components. Most (HTML, CSS, Javascript, JSON, XML, etc) are text-based. They can be efficiently compressed for transfer via gzip, supported by all mainstream webservers and browsers. But image and video files are binary, non-text files, and generally are not worth auto-compressing in the webserver.

Most web traffic consists of image file downloads, specifically JPEG images. JPEG files use so much bandwidth that Google has tried improving them by introducing an alternative format[16]. JPEG images are not compressed by the webserver because JPEG is a binary format which does not compress well because it includes its own built-in compression, and generally it is up to the people creating the images to select an appropriate compression setting when the file is saved.

The JPEG quality settings most used by graphics professionals tend to be highly conservative because Compression and image quality are inversely proportional and graphics people are interested in utmost visual quality and not in spending time worrying about network efficiency.

The result of overly conservative JPEG compression and webservers' inability to compress them any further means that many images on the web are too large. JPEG's overwhelming popularity as the most common image format means that many pages contain dozens of JPEG images.

These bloated images take longer to transfer, leading to extended load time, which does not produce a good viewer experience. People hate to wait.

In order to understand how to optimize JPEGs for size first we must learn more about the JPEG format.

"Quality" Details

JPEG images contain a single setting usually referred to as "Quality", and it is usually expressed as a number from 1-100, 100 being the highest. This knob controls how aggressive the editing program is when saving the file. A lower quality setting means more aggressive compression, which generally leads to lower image quality. Many graphics people are hesitant to reduce this number below 90-95.

But how exactly does "quality" affect the image visibly? Does the same image at quality 50 look "half as good" than quality 100? What does half as good even mean, anyway? Can people tell the difference between an image saved at quality 90 and quality 89? And how much smaller is an image saved at a given quality? Is the same image at quality 50 half as large as at 100?

Here is a chart of the approximate relationship between the visual effect of "quality" and the size of the resulting file.

100% |#*******
 90% | #      ******* Visual Quality (approximate)
 80% |  #            ********
 70% |   #                   ********    --- noticeably worse at some point ---
 60% |    ##                         *******
 50% |      ###                             ******
 40% |         #####                              ****
 30% |    File Size ######                            ***
 20% |                    ################               *****
 10% |                                    ####################******
  0% +---------------------------------------------------------------
     100    90    80    70     60    50    40     30     20    10    0

The precise numbers vary for each image, but the convex shape of the "Visual Quality" curve and the concave "File Size" curve hold for each image. This is the key to reducing file size.

For an average JPEG there is a very minor, mostly insignificant change in apparent quality from 100-75, but a significant filesize difference for each step down. This means that many images look good to the casual viewer at quality 75, but are half as large than they would be at quality 95. As quality drops below 75 there are larger apparent visual changes and reduced savings in filesize.

Even More Detail

So, why not just force all JPEGs to quality 75 and leave it at that?

Some sites do just that:

Google Images thumbnails:  74-76
Facebook full-size images: 85
Yahoo frontpage JPEGs:     69-91
Youtube frontpage JPEGs:   70-82
Wikipedia images:          80
Windows live background:   82
Twitter user JPEG images:  30-100, apparently not enforcing quality

This is a fine strategy and is low-risk, straight-forward and inexpensive.

But for optimal results it is not that simple. Compression results rely heavily on the data being compressed. This means that visual quality is not uniform for all images at a given quality setting. Imposing a single quality, no matter what it is, will be too low for some images, resulting in poor visual quality and will be too high for others, resulting in wasted space.

So we are left with a question:

What is the optimal quality setting for a given image with regard to filesize but still remain indistinguishable from the original?

The widely accepted answer, as formulated by the 'JPEG image compression FAQ'[5]:

This setting will vary from one image to another.

So, there is no one setting that will save space but still ensure that images look good, and there's no direct way to predict what the optimal setting is for a given image.

Looking For Patterns

Based on what we know, the easiest way around our limitations would be to generate multiple versions of an image in a spectrum of qualities and have a human choose the lowest quality version of the image of acceptable quality.

I proceded in this way for a variety of images, producing an interactive image gallery. Along with each image version I included several statistical measures available from the image processing library and a pattern emerged.

Given a high quality original image, apparent visual quality began to diminish noticably when mean pixel error rate exceeded 1.0.

This metric measures the amount of change, on average, each pixel in the new image is from the original. Specifically, JPEGs break image data into 8x8 pixel blocks. The quality setting controls the amount of information available to encode quantized color and brightness information about a block. The less space available to store each block's data the more distorted and pixelated the image becomes -- you can verify this by inspecting an image saved at quality 0 -- each 8x8 block of pixels should be assigned a single color.

The change in pixel error rate is not directly related to the quality setting, again, an image's ultimate fate lies in its data; some images degrade rapidly within 1 or 2 quality steps, while others compress with little visible difference from quality 95 to quality 50.

Automating the Process

Given the aforementioned observation of high-quality images looking similar within a mean pixel error rate of 1.0, the method of determining an optimal quality setting for any given JPEG is clear: generate versions of an image at multiple different quality settings, and find the version with the mean pixel error rate nearest to but not exceeding 1.0.

Using quality bounds of [95, 50] we perform a binary search of the quality space, converging on the lowest quality setting that produces a mean pixel error rate of < 1.0.

For general-purpose photographic images with high color counts the above method yields good results in tests.

Limitations

One notable exception is in low color JPEG images, such as gradients and low- contrast patterns used in backgrounds. The results at ~1.0 are often unacceptably pixelated. Our image-wide statistical measure is not "smart" enough to catch this, so currently images with < 4096 colors are passed through unchanged. For reference the "google" logo on google.com contains 6438 colors. In practice this is not a problem for a typical image-heavy website because there are relative few layout-specific "background" graphics which can be (and are) handled separately from the much larger population of "foreground" images.

Implementation

The implementation for the standalone client and apache module is in C. The original script is in Perl. The interactive image gallery in web/ uses PHP. All use the excellent ImageMagick graphics library.

Performance

0.5-2 seconds for a typical image on a typical 2015 machine. Automatically scales to multiple CPUs via Imagemagick's built-in OpenMP support.

Conclusion

In conclusion I have created an automated method for generating optimally-sized JPEG images for casual use that can be integrated into existing workflows. The method is low cost to deploy and run and can yield appreciable and direct benefits in the form of improving webserver efficiency, reducing website latency, and most importantly improving overall viewer experience. This method is generally applicable and can be applied to any collection of or website containing JPEG images.

References

  1. "JPEG" Wikipedia, The Free Encyclopedia. Wikimedia Foundation, Inc. 3 July 2011. Web. 7 Jul. 2011. http://en.wikipedia.org/wiki/JPEG
  2. "Joint Photographic Experts Group" Wikipedia, The Free Encyclopedia. Wikimedia Foundation, Inc. 29 June 2011. Web. 7 Jul. 2011. http://en.wikipedia.org/wiki/Joint_Photographic_Experts_Group
  3. "Information technology – Digital compression and coding of continuous-tone still images – Requirements and guidelines" 1992. Web. 7 Jul. 2011 http://www.w3.org/Graphics/JPEG/itu-t81.pdf
  4. "Independent JPEG Group" 16 Jan. 2011 Web 7 Jul. 2011 http://www.ijg.org/
  5. "JPEG image compression FAQ" Lane, Tom et. al. 28 Mar. 1999 Web. 7 Jul. 2011 http://www.faqs.org/faqs/jpeg-faq/part1/preamble.html
  6. "JPEG Discrete cosine transform". Wikipedia, The Free Encyclopedia. Wikimedia Foundation, Inc. 3 July 2011. Web. 7 Jul. 2011. http://en.wikipedia.org/wiki/JPEG#Discrete_cosine_transform
  7. "GetImageQuantizeError()" ImageMagick Studio LLC. Revision 4754 [computer program] http://trac.imagemagick.org/browser/ImageMagick/trunk/MagickCore/quantize.c#L2142 (Accessed July 7 2011)
  8. "A Color-based Technique for Measuring Visible Loss for Use in Image Data Communication" Melliyal Annamalai, Aurobindo Sundaram, Bharat Bhargava 1996. Web 10 Jul 2011 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.50.8313
  9. "An Evaluation of Transmitting Compressed Images in a Wide Area Network" Melliyal Annamalai, Bharat Bhargava 1995. Web 10 Jul 2011 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.7201
  10. "ImageMagick v6 Examples -- Common Image Formats: JPEG Quality vs File Size" ImageMagick Studio LLC http://www.imagemagick.org/Usage/formats/#jpg_size
  11. "JPEG Compression, Quality and File Size" ImpulseAdventure.com, Calvin Hass http://www.impulseadventure.com/photo/jpeg-compression.html
  12. "Designing a JPEG Decoder & Source Code" ImpulseAdventure.com, Calvin Hass http://www.impulseadventure.com/photo/jpeg-decoder.html
  13. "JPEG Compression" Gernot Hoffmann. 18 Sep 2003. Web. 13 Aug 2011 http://www.fho-emden.de/~hoffmann/jpeg131200.pdf
  14. "Optimization of JPEG (JPG) images: good quality and small size" Alberto Martinez Perez. 16 Sep 2008. Web. 14 Aug 2011 http://www.ampsoft.net/webdesign-l/jpeg-compression.html
  15. "JPEG: Joint Photographic Experts Group" http://www.cs.auckland.ac.nz/compsci708s1c/lectures/jpeg_mpeg/jpeg.html
  16. "WebP: A new image format for the Web", Google, 2012. Web. 31 Jan 2012. http://code.google.com/speed/webp/ 17 "New WebP Image Format Could Send JPEG Packing", Rob Spiegel, 10 Oct 2010. Web. 31 Jan 2012 http://www.technewsworld.com/story/New-WebP-Image-Format-Could-Send-JPEG-Packing-70945.html

Technical Notes

License

This software is licensed under the MIT license.
See LICENSE-MIT.txt and/or http://www.opensource.org/licenses/mit-license.php

Installation

Prerequisites

On Ubuntu Linux via apt-get:

$ sudo apt-get install imagemagick libgraphicsmagick1-dev libmagickwand-dev perlmagick apache2-prefork-dev

On Redhat Linux via yum:

$ sudo yum install Imagemagick ImageMagick-devel Perlmagick apache2-devel

On Unix via source:

$ cd /usr/local/src                                                # source directory of choice
$ sudo wget -nH -nd ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz
$ sudo gzip -dc ImageMagick-6.7.1-3.tar.gz | sudo tar xvf -        # extract
$ cd ImageMagick-6.7.1-3                                           # change dir
$ sudo ./configure                                                 # configure
$ sudo make -j2                                                    # compile
$ sudo make install                                                # install

imgmin

from source: see top of README

Examples

Generic

$ time ./src/imgmin examples/Afghan-Girl-by-Steve-McCurry.jpg Afghan-Girl-by-Steve-McCurry-after.jpg
Before quality:85 colors:44904 size: 58.8kB type:TrueColor format:JPEG 0.27/0.06@72 0.36/0.08@66 0.42/0.10@63 0.44/0.06@61
After  quality:61 colors:51650 size: 29.6kB saved: 29.2kB (49.7%)

My 2014 Macbook

$ time imgmin examples/lena1.jpg examples/lena1-after.jpg
Before quality:92 colors:73822 size: 89.7kB type:TrueColor format:JPEG 0.93/0.02@76 1.13/0.02@68 1.01/0.02@72
After  quality:72 colors:74073 size: 35.8kB saved: 53.8kB (60.0%)

real    0m0.696s
user    0m0.590s
sys     0m0.060s

imgmin's People

Contributors

brucealdridge avatar jibsen avatar kornelski avatar lex-2008 avatar rflynn avatar tenzer avatar yoavweiss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

imgmin's Issues

Handle invalid min and max output quality better

If you specify QUALITY_OUT_MAX less than QUALITY_OUT_MIN+2, imgmin will bug out with an error message such as the following:

Before quality:94 colors:93196 size:247.6kB type:TrueColor format:JPEG
imgmin: wand/magick-wand.c:181: DestroyMagickWand: Assertion `wand !=(MagickWand *) ((void *)0)' failed.
Aborted (core dumped)

It would be better if imgmin either give a decent error message, ie. referring the user to check the out min/max numbers, or if only the min or max value is given, it could automatically push the other value to be a value which makes sense, ie. 10 apart from the value specified.

comprehensive before/after corpus

instead of focusing on a single stat, build hundreds of before/after images which can be used for testing and also a corpus for a more flexible machine learning approach.

Abandoned?

Hello,

Wanted to try the project, but this won't compile.

apache filter module port

currently we can demonstrate imgmin/httpd automation via the mod_ext_filter, but this is too slow for production.

port imgmin to native apache filter module for performance

Logo

I needed a logo for my presentation, so I've made one for you;

90

mod_pagespeed port/integration

integrate imgmin into mod_pagespeed arch. make it optional.

this will make imgmin instantly available to a wide audience.

Chroma Downsampling Lowers Visual Quality

Line 337 of imgmin.c contains:

        (void) MagickSetImageProperty(mw, "jpeg:sampling-factor", "2x2");

I find that the quality is noticeably and significantly better if I comment/remove that line (although the size is increased some).

Here are some test images.

graphic made in GIMP, saved as quality 100 JPEG:
original
imgmin output, chroma downsampling 2x2
imgmin output, chroma downsampling off

random image from rawsamples.ch, resized, saved as quality 100 JPEG:
original
imgmin output, chroma downsampling 2x2
imgmin output, chroma downsampling off

random image from Google Images (and ultimately from thewallgans.com, a wallpaper site), resized, saved as quality 100 JPEG:
original
imgmin output, chroma downsampling 2x2
imgmin output, chroma downsampling off

Every area with fine detail is blurred significantly, and colors tend to look less vivid, in the chroma-downsampled versions.

Can't install on Mac OS X

Hi. This looks like an amazing tool. And thanks for the very informative readme.

But I'm having trouble building on Mac OS X Lion...

MBP:imgmin callum$ make
make -C src
make -C apache2
apxs2 -I `pwd`/.. `MagickWand-config --cppflags` `MagickWand-config --ldflags --libs|xargs` -Wc,-DIMGMIN_LIB -Wc,-W -Wc,-Wall -Wc,-Wno-unused-parameter -c mod_imgmin.c -c ../imgmin.c
/bin/sh: apxs2: command not found
make[2]: *** [mod_imgmin.la] Error 127
make[1]: *** [mod_imgmin] Error 2
make: *** [all] Error 2

OS X does seem to have apxs already:

MBP:imgmin callum$ apxs
Usage: apxs -g [-S <var>=<val>] -n <modname>
       apxs -q [-S <var>=<val>] <query> ...
       apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]
               [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]
               [-Wl,<flags>] [-p] <files> ...
       apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...
       apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...

...but not apxs2.

Googling "mac apxs2" etc. hasn't been very helpful. Any ideas?

Thanks
Callum

JPEG image terminated by signal SIGSEGV (Address boundary error)

imgmin v1.1 When performing overflow happened, terminated by signal SIGSEGV (Address boundary error).

imgmin /usr/local/Library/Homebrew/test/fixtures/test.jpg out.jpg
Before quality:95 colors:1 size:  0.3kB type:Palette format:JPEG
terminated by signal SIGSEGV (Address boundary error)

# file '/usr/local/Library/Homebrew/test/fixtures/test.jpg'
  /usr/local/Library/Homebrew/test/fixtures/test.jpg: JPEG image data, JFIF standard 1.01

Use interpolation/extrapolation instead of bisection

kornelski/imgmin@pornel:0fe0e25...pornel:d0b9172

Instead of searching for quality using bisection method, which is slow, I'm trying to find exact quality needed by modelling jpeg quality vs dssim ratio as a curve, and finding the desired point on that curve.

I think I've told my math teacher that polynomials are stupid and I'm never going to use them… but…

The curve is a polynomial constructed from 3 points, and the points represent jpeg-quality to dssim relationship from the last 3 runs (default points are used for the first couple of runs).

It needs a bit of tweaking, but when it works it finds exact quality in 3-4 steps.

JPEG Lossy

I have an idea on optimization of JPEG Lossy

What is JPEG progressive? Actually it is a number of images where quality of each following image is higher previous the image.

We will take this image

content

JPEG Scan Killer project.

We receive 16 images:

File butteraugli dssim Size
scan_002 5,630772 0.15174437 15 871
scan_003 5,862817 0.05783141 22 461
scan_004 4,675802 0.03125192 31 356
scan_005 2,387352 0.00364845 109 247
scan_006 2,327576 0.00254360 152 963
scan_007 2,271701 0.00243935 160 207
scan_008 2,240952 0.00250675 194 622
scan_009 1,813344 0.00151375 200 877
scan_010 1,234480 0.00071220 222 874
scan_011 1,031184 0.00029957 274 295
scan_012 0,978295 0.00030116 305 552
scan_013 0,909136 0.00025336 329 976
scan_014 0,754250 0.00006819 392 083
scan_015 0,595898 0.00004337 439 168
scan_016 0,000000 0.00000000 480 790

How it is possible to create with the help -scans technology of optimization of JPEG lossy?

JPEG consists of blocks of 8х8 pixels. Perhaps, there is a sense to segment the image and to optimize each part separately. Later to connect parts of the image in the uniform optimized image. Principle of work of the betterjpeg program.

I wanted to learn, your opinion on the matter.

Build fails on Ubuntu 16.04

Similar to this issue from early 2015 #51 on Ubuntu 16.04, following the build instructions precisely (apt installs ImageMagick v6.8.9) building imgmin fails. Also worth noting I had to manually export MAGICK_CONFIG=/usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/Magick-config or config/make would fail to find the config and would result in an error like --cflags: command not found since the MAGICK_CONFIG default value falls back to an empty string.

The error details:

root@1edbd36cf720:/root/imgmin-1.1# make
make  all-recursive
make[1]: Entering directory '/root/imgmin-1.1'
Making all in src
make[2]: Entering directory '/root/imgmin-1.1/src'
gcc -W -Wall -Os  `/usr/bin/GraphicsMagickWand-config --cflags --cppflags` -o imgmin imgmin.c dssim.c `/usr/bin/GraphicsMagickWand-config --ldflags --libs` -lm
imgmin.c:28:29: fatal error: wand/MagickWand.h: No such file or directory
compilation terminated.
dssim.c: In function ‘convert_image_row’:
dssim.c:304:55: warning: unused parameter ‘inf’ [-Wunused-parameter]
 static void convert_image_row(const dssim_info *const inf, float *const channels[], const int num_channels, const int y, const int width, void *user_data)
                                                       ^
Makefile:566: recipe for target 'imgmin' failed
make[2]: *** [imgmin] Error 1
make[2]: Leaving directory '/root/imgmin-1.1/src'
Makefile:355: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/root/imgmin-1.1'
Makefile:296: recipe for target 'all' failed
make: *** [all] Error 2

I'm using Docker, phusion/baseimage:0.9.19 which is ubuntu 16.04. Here's a minimal Dockerfile that will reproduce the issue:

FROM phusion/baseimage:0.9.19

# Use baseimage-docker's init system.
CMD [ /sbin/my_init ]

# upgrade
RUN apt-get update && apt-get dist-upgrade -y

# build tools (uninstall afterwards)
RUN apt-get install -y \
  build-essential \
  dh-autoreconf \
  wget

RUN apt-get install -y libpng-dev
RUN cd && wget https://github.com/pornel/pngquant/archive/2.5.0.tar.gz && \
  tar xf 2.5.0.tar.gz && \
  cd pngquant-2.5.0 && \
  make && \
  make install

RUN apt-get install -y imagemagick libgraphicsmagick1-dev libmagickwand-dev perlmagick libmagick++-6-headers libmagick++-dev
ENV MAGICK_CONFIG=/usr/bin/GraphicsMagickWand-config
RUN cd && wget https://github.com/rflynn/imgmin/archive/v1.1.tar.gz && \
  tar xf v1.1.tar.gz && \
  cd imgmin-1.1 && \
  autoreconf -fi && \
  ./configure && \
  make && \
  make install

You can build the image with docker build -t thumbor . when in a dir with the Dockerfile above.

It will fail but you can still shell in with docker run -t -i thumbor /sbin/my_init -- bash -l. After you shell in you'd probably want to rerun imgmin build step (it fails so it won't be in the image) with cd /root && wget https://github.com/rflynn/imgmin/archive/v1.1.tar.gz && \ tar xf v1.1.tar.gz && \ cd imgmin-1.1 && \ export MAGICK_CONFIG=/usr/bin/GraphicsMagickWand-config && autoreconf -fi && \ ./configure && \ make && \ make install

Would appreciate any help. Thanks.

Ubuntu Make Problem

Hi,

I'm encountering a "make" problem on ubuntu server 13.04 (GNU/Linux 3.8.0-33-generic x86_64).

Everything seems to be fine until the make command. I was able to install imgmin successfully on a 12.04 LTS ubuntu server, but not on this new machine. I love this script it is fast and the ratio quality/weight is just wonderful I think.

Below, the output in terminal:

root@pop-front1:~/imgmin# make
make all-recursive
make[1]: Entering directory /root/imgmin' Making all in src make[2]: Entering directory/root/imgmin/src'
gcc -W -Wall -Os MagickWand-config --cflags --cppflags -o imgmin imgmin.c MagickWand-config --ldflags --libs
imgmin.c: In function ‘do_png’:
imgmin.c:389:9: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
imgmin.c:399:9: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
imgmin.c:406:9: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
imgmin.c:429:9: warning: initialization discards ‘const’ qualifier from pointer target type [enabled by default]
imgmin.c:368:32: warning: unused parameter ‘mw’ [-Wunused-parameter]
imgmin.c:369:50: warning: unused parameter ‘opt’ [-Wunused-parameter]
make -C apache2
make[3]: Entering directory /root/imgmin/src/apache2' if [ "apxs2" != "" ]; then \ apxs2 -Ipwd/..MagickWand-config --cppflags --ldflags --libs|xargs-Wc,-DIMGMIN_LIB -Wc,-W -Wc,-Wall -Wc,-Wno-unused-parameter -c mod_imgmin.c ../imgmin.c; \ fi Use of uninitialized value $includedir in concatenation (.) or string at (eval 9) line 1. apxs:Error: Unknown option: f. Usage: apxs -g [-S <var>=<val>] -n <modname> apxs -q [-S <var>=<val>] <query> ... apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]] [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>] [-Wl,<flags>] [-p] <files> ... apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ... apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ... make[3]: *** [mod_imgmin_la] Error 1 make[3]: Leaving directory/root/imgmin/src/apache2'
make[2]: *** [mod_imgmin] Error 2
make[2]: Leaving directory /root/imgmin/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory/root/imgmin'
make: *** [all] Error 2

Do you know what this could be ?

Thanks

compile error w/ apxs

Hello,

I was not able to compile on my system (Fedora 17), as it was failing on the call to apxs, with an error stating:

apxs:Error: Unknown option: f.

After looking at what was going on, the results on my system of MagickWand-config --cppflags --ldflags --libs|xargs resulted in the following:

-fopenmp -I/usr/include/ImageMagick -lMagickWand -lMagickCore -lMagickWand -lMagickCore

I was able to get past this by updating that portion of the Makefile with the following to strip out that option (believe real change would have to go into Makefile.am):

MagickWand-config --cppflags --ldflags --libs |xargs |sed "s/-fopenmp\s//"

Afterwards, I was able to get it to compile. I do not know if this negatively affects what is built, I have no intention of using the apache module. It might also be nice to be able to override whether the module is built by including an --disable option for apache (sorry if it is there and I did not see it, am terrible with autotools).

Thank you for this tool, am excited to see how much it will shave off my images!

-Mike

when savings <= 1% don't bother

When savings is > 0 but is very small, just use the original. Often the reduction in quality is disproportional to the meager reduction in size and is not worth it.

Optimize huffman trees, and make all jpegs progressive.

I don't know how hard this'd be or whether or not imagemagick allows you to optimize the huffman trees/make the images progressive but I do know that jpegtran allows that to happen on its own. Adding those options would also greatly help reduce the total space required.

Crap I can't edit it.

So here's the rest of it.

The optimization passes should add that at the final step once you've found the best quality level since it definitely helps reduce the total size.

OK, it's not a ton with the example images(in the after folder). It goes down by ~4%. Which isn't insane, but still the whole idea of this thing to is to make the images as small as possible without visual quality loss.

Progressive JPEG

Is it possible to convert to progressive JPEGs?

I think convert -interlace JPEG after-imgmin.jpg output.jpg will degrade quality.

Apache mod build failure on OS X

I'm trying to compile on OS X 10.9 that only has some half-baked Apache included by Apple with the OS:

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C apache2
if [ "apxs" != "" ]; then \
        apxs -I `pwd`/.. `MagickWand-config --cppflags --ldflags --libs|xargs` -Wc,-DIMGMIN_LIB -Wc,-W -Wc,-Wall -Wc,-Wno-unused-parameter -c mod_imgmin.c ../imgmin.c; \
    fi
/usr/share/apr-1/build-1/libtool --silent --mode=compile /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.9.xctoolchain/usr/bin/cc    -DDARWIN -DSIGPROCMASK_SETS_THREAD_MASK -I/usr/local/include -I/usr/include/apache2  -I/usr/include/apr-1   -I/usr/include/apr-1  -DIMGMIN_LIB -W -Wall -Wno-unused-parameter -I/Users/kornel/imgmin/src/apache2/.. -I/usr/local/Cellar/imagemagick/6.8.9-7/include/ImageMagick-6 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16 -DMAGICKCORE_HDRI_ENABLE=0 -DMAGICKCORE_QUANTUM_DEPTH=16  -c -o mod_imgmin.lo mod_imgmin.c && touch mod_imgmin.slo
env: /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.9.xctoolchain/usr/bin/cc: No such file or directory
apxs:Error: Command failed with rc=65536
.
make[3]: *** [mod_imgmin_la] Error 1
make[2]: *** [mod_imgmin] Error 2
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

The path /Applications/Xcode.app/Contents/Developer/Toolchains/OSX10.9.xctoolchain/usr/bin/cc looks quite suspicious.

--version support

Please support imgmin --version.
I feel lost after building imgmin.

Problem building on Ubuntu 14.10 (AM_INIT_AUTOMAKE)

Following instructions I've hit an error on autoconf:

$ autoconf -fi
autoconf: error: invalid option `-fi'
Try `autoconf --help' for more information.

Running with separated arguments also errors:

$ autoconf -f -i
configure.ac:8: error: possibly undefined macro: AM_INIT_AUTOMAKE
      If this token and others are legitimate, please use m4_pattern_allow.
      See the Autoconf documentation.

So I've dropped -f and autoconf finishes without errors, but configure does not:

$ autoconf -i
$ ./configure 
./configure: line 2145: syntax error near unexpected token `imgmin,'
./configure: line 2145: `AM_INIT_AUTOMAKE(imgmin, 0.7)'

Can't build on mac os

Hello! Nice to meed U!

I tried to build imgmin for amd64 linux but didn't succeed.
Can U, please build it for me? I know it sounds stupid, but i'm trying to do that on darwin inside docker container with a slow internet connection. It takes hours and fails.
Help me, please.

Checking if lossless png is more efficient

I know this project is to optimize lossy compression, but I guess there are many cases in which lossless compression actually yields better compression rate at superior quality. Examples could be backgrounds with gradients or images with unicolor areas.

Would it be possible to simply generate a PNG for such 'usual suspects' and see if its size is lower than the JPG?

JPEG: Possibility to tweak quality threshold/tolerance?

We have just implemented imgmin on a project and are really happy with the over all result. But in some images we have found noticeable artefacts.

Is there some way we can decrease the threshold/tolerance when picking the quality for a given image? Just a slight tweak will hopefully do the trick.

PS. Thanks for an amazing contribution to a faster interwebz.

MagickWand-config location in Debian jessie

I've added in configure.ac

ECK_PROGS(MAGICK_CONFIG, MagickWand-config Magick-config, "/usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/MagickWand-config")

then

make
make  all-recursive
make[1]: Entering directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin'
Making all in src
make[2]: Entering directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin/src'
gcc -std=gnu99 -W -Wall -Os  `/usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/MagickWand-config --cflags --cppflags` -o imgmin imgmin.c dssim.c `/usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16/MagickWand-config --ldflags --libs` -lm
imgmin.c: In function ‘convert_row_callback’:
imgmin.c:197:51: warning: unused parameter ‘inf’ [-Wunused-parameter]
 void convert_row_callback(const dssim_info *const inf, float *const channels[], const int num_channels, const int y, const int orig_width, void *user_data) {
                                                   ^
imgmin.c:197:91: warning: unused parameter ‘num_channels’ [-Wunused-parameter]
 void convert_row_callback(const dssim_info *const inf, float *const channels[], const int num_channels, const int y, const int orig_width, void *user_data) {
                                                                                           ^
imgmin.c:197:115: warning: unused parameter ‘y’ [-Wunused-parameter]
 void convert_row_callback(const dssim_info *const inf, float *const channels[], const int num_channels, const int y, const int orig_width, void *user_data) {
                                                                                                                   ^
imgmin.c: In function ‘do_png’:
imgmin.c:429:9: warning: initialization discards ‘const’ qualifier from pointer target type
         char * const argv[] = { "pngnq", "-f", src, (char*)0};
         ^
imgmin.c:439:9: warning: initialization discards ‘const’ qualifier from pointer target type
         char * const argv[] = { "pngcrush", "-force", src, out, (char*)0 };
         ^
imgmin.c:446:9: warning: initialization discards ‘const’ qualifier from pointer target type
         char * const argv[] = { "pngquant", "-force", "256", src, (char*)0 };
         ^
imgmin.c:469:9: warning: initialization discards ‘const’ qualifier from pointer target type
         char * const argv[] = { "cp", files[0].path, dst, NULL };
         ^
imgmin.c:408:32: warning: unused parameter ‘mw’ [-Wunused-parameter]
 static void do_png(MagickWand *mw, const char *src, const char *dst,
                                ^
imgmin.c:409:50: warning: unused parameter ‘opt’ [-Wunused-parameter]
                     const struct imgmin_options *opt)
                                                  ^
dssim.c: In function ‘convert_image_row’:
dssim.c:304:55: warning: unused parameter ‘inf’ [-Wunused-parameter]
 static void convert_image_row(const dssim_info *const inf, float *const channels[], const int num_channels, const int y, const int width, void *user_data)
                                                       ^
make[2]: Leaving directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin/src'
make[2]: Entering directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin'
make[2]: Leaving directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin'
make[1]: Leaving directory '/root/debian-server-tools/monitoring/cpu-speed/x/imgmin'

It produced imgmin executable.

build on OS X

figure out some combination of build parameters against imagemagick on osx

Ubuntu Instructions don't work

after installing packages
sudo apt-get install imagemagick libgraphicsmagick1-dev perlmagick apache2-prefork-dev

I get magickwand errors on stock ubuntu machines

No package 'MagickWand' found
In file included from imgmin.c:26:0:
imgmin.h:7:29: fatal error: wand/MagickWand.h: No such file or directory
compilation terminated.

Use structural similarity

I've made my SSIM implementaiton usable directly in C (ignore the CLI tool that reads PNG, just set bitmaps directly via C API).

This is much more accurate than ImageMagick's MSE metric.

It may even be faster, because my implementation doesn't need to re-decode source image (you can set it once and only swap modified version).

Imgmin now gives god awful results.

I can't find my really old version of imgmin to compare but I just ran an image through it and it set the after quality to 65 as the "perfect" quality even though the image is full of jpeg artifacts normally imgmin has always given me images that I can't tell the difference between at 100% zoom only if I zoom in waymore than that can I begin to notice it.

imgmin's "optimzied" file that it says is nearly identical to the original image when it clearly is not as there is a crapton of compression artifacts throughout the image.
2016-10-08-000043- optimized
original file quailty was 90 non-progresive non optimized even huffman optimied via jpegtran
2016-10-08-000043

Do not use Debian's pngquant package

Debian's pngquant is 13 years old and has very poor image quality compared to modern pngquant.

Consider using packages from http://pngquant.org

The new pngquant also has --quality argument which makes it automatically select number of colors required to achieve given quality (takes unit similar to JPEG's quality, optimizes for mean square error).

Allow non-verbose mode

Something I'd like to have it do is to just show space saved, or be able to show nothing. As it is now, it's filling up the terminal with information that I'd rather not see. So if there is a way to make it so that it just shows "space saved", or "skipped". That'd be amazing.

As stated it doesn't work with those options that the author of this software said. This is on debian stable.

Running the following script that I've written to do the "recursive" thing does not work how he said it should. Nor does /dev/null work.

#/bin/bash
cd $1;
find -iname "*.jpg" >> tmp;
sed -i "s/.\///" tmp;

FILENAME=tmp;
while read line
do
      imgmin "$line" "$line" | grep -o 'saved:.*';
      jhead -purejpg "$line";
done < $FILENAME

Please note I've also tried using it with > /dev/null and it doesn't work either, so thus it's doing something weird.

I'm on debian with the following uname.

Linux sager-laptop 2.6.39-bpo.2-amd64 #1 SMP Tue Jul 26 10:35:23 UTC 2011 x86_64 GNU/Linux

I compiled it for 64bits using the following gcc commands.

-march=core2 -O3

other than that it was just a straight compile. I have no idea why it's acting so weird and not working with the utilities as it should.

allow Imgmin to do *.jpg and thus optimize an entire directory

I know that this is probably not something that you were thinking of when you first made it, but not being able to go through and run it on a directory of images that i have is a major annoyance. I know it's made for websites, but I wouldn't mind making my photos that I have on my computer take up less space.

Anyway this is an awesome utility from it's description, and also running it.

Option to skip building of Apache module

Re #34 I'd prefer not to build Apache module at all, but I don't see the option for that in ./configure --help and the generated makefile doesn't have imgmin target (which I hoped would just build the commandline version):

$ make imgmin
make: *** No rule to make target `imgmin'.  Stop.

Very good product

This is like JPEGmini w/o infrastructure.
Thank you!

Could you explain what are pngnq pngcrush pngquant for in case of JPEGs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.