Compressing an image to make it less than 4KB - image

I have an image of a person and I want to compress it to make it less than 4KB. I need to compress it and still have the face of the person recognizable even if the image will shrink.

Here is Theresa May at 142kB:
and resized to 72x72 and converted to greyscale and reduced to 2kB with ImageMagick at the command line:
convert original.jpg -resize 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg
I can still recognise her.
Here is some other guy reduced to 1kB and I can still recognise him too:
ImageMagick is installed on most Linux distros and is available for macOS and Windows. Bindings are available for Python, PHP, Ruby, Javascript, Perl etc.
If you had further knowledge about your images, or your recognition algorithm, you may be able to do better. For example, if you knew that the centre of the image was more important than the edges, you could slightly blur, or reduce contrast in relatively unimportant areas and use the available space for more details in the important areas.

Mark Setchell has the right idea. But I might suggest one potential minor improvement. Remove any meta data including profiles, EXIF data etc. You can do that by either adding -strip
convert input.jpg -strip -resize 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg
or by using -thumbnail rather than -resize. The former automatically does the strip.
convert input.jpg -thumbnail 72x72 -colorspace gray -define jpeg:extent=2kb result.jpg

Related

Batch Resize Photos While Maintaining the Aspect Ratio AND Fitting to a specific pixel size

I am looking to batch resize pictures to a specific pixel size while maintaining the aspect ratio. Is their a way that the picture aspect can be preserved and the rest of the space can be filled in with white? For example, I resize an image to 200 x 200 and due to preserving the aspect ratio it is changed to 200 x 194. I would like the actual image to remain 200 x 194 and white space to fill in the remaining area to create an image that is 200 x 200 px. Thank you in advance!
You can do that with ImageMagick which is included in most Linux distros and is available for macOS and Windows.
Just in Terminal, or Command Prompt on Windows:
magick input.jpg -background white -resize 200x200 -gravity center -extent 200x200 result.jpg
If you have many files to do, you may be better using ImageMagick's mogrify command, which will do them all in one go for you! So make a new directory called processed for the output files and then use this to process all PNG files in the current directory:
magick mogrify -path processed -background white -resize 200x200 -gravity center -extent 200x200 '*.png'
I don't know if you are on Windows or not, so you may or may not need the single quotes around the filenames at the end of that command. Basically, it determines whether the expansion of the filename list is done by the shell (which has limitations on the number of files), or internally by ImageMagick (which does not).
If you are running anything older than v7, the commands become:
convert input.jpg ...
or
mogrify ...

How to give an image an old, dusty appearance with faded colours?

I have images of old paintings. The paintings are old and dusty with faded colours as shown here.
How do I give any image this type of an 'old' appearance? I couldn't find any filters or openCV functions to achieve this type of look?
EDIT: My question is different as the other one solves the problem using the sepia filter and using the grain effect. I'm not looking for that sort of an appearance. I want my image to look like an old damaged painting. This means that the colours should be faded and it should have an overall dusty appearance.
There's no real need to write any code and use OpenCV, since you can do all that on the command-line with ImageMagick which is installed on most Linux distros and is available for macOS and Windows.
First, fading. This can be simulated by reducing the saturation of an image. So if we start with this Mona Lisa image:
We can fade her using this command to leave the brightness unchanged at 100% of its original value and reduce the saturation to 50% of its original value. I am intentionally "over-egging" everything so you can see it clearly. You should maybe be more subtle.
convert mona.jpg -modulate 100,50 result.jpg
Next, vignetting - or dark corners. You can use something like this:
convert mona.jpg \
\( +clone -fill white -colorize 100 -background "gray(50%)" -vignette 0x15+1+1% \) \
-compose multiply -composite result.jpg
The 0x15 controls the roll-off, or how gradual the change is, so increase the 0x15 if you want a smoother roll-off or go down to 0x5 if you want it harder. The +1+1% means that the ellipse will be 1% smaller than the width of the image and 1% smaller than the height of the image. So if you want a smaller light hole and bigger dark corners, go for +10+10%. The degree of darkening is controlled by the gray(50%) so you can diddle with that till you are happy too :-)
Finally, dust. Best thing is to get a PNG image of some dust, resize it to match the size of your image and overlay it.
First get the size of Mona:
identify mona.jpg
mona.jpg JPEG 403x600 403x600+0+0 8-bit sRGB 57130B 0.000u 0:00.000
So, she is 403x600. Here is a sample of some dust - again, you can be more subtle - I am just being heavy-handed so it shows:
Let's resize the dust to match and overlay it:
convert mona.jpg \( dust.png -resize 403x600\! \) -composite result.jpg
Then you can combine all three effects, fading, vignetting and dust, into a single command:
convert mona.jpg -modulate 100,50% \
\( +clone -fill white -colorize 100 -background "gray(50%)" -vignette 0x15+1+1% \) \
-compose multiply -composite \
\( dust.png -resize 403x600\! \) -composite result.jpg
If you have lots of images to process, you can script the whole lot to be done in parallel very easily with GNU Parallel - see some of my other answers for examples.
Keywords: artificial ageing, image ageing, command-line, command line, ImageMagick, magick, old, old photo, photo effect, convert, dust, scratches, fading, faded.
I would suggest using a style transfer tool, rather than manually coming up with a procedure to mimic the style of an old painting. There are plenty free style transfer tools and libraries available.
I would suggest using OpenCV various filters to create the effect you need. You have to try various filters and try to figure what works for you, But I have suggestions which you can try.
For color, fading try Erode and Dilate with small kernel size.
Next, add some noise, Salt and Pepper will do just fine, also try gaussian filter after applying noise. Salt and Pepper is non-linear noise and Gaussian is a linear filter so it will just spread the noise, but keep the filter kernel small.
Try finding some images of dust, torn page edges (WITHOUT BACKGROUND) like in the following link:
https://www.google.co.in/searchq=dust+png+images&newwindow=1&rlz=1C1CHBF_enIN797IN798&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjtq7ZvfPcAhXJO48KHQ2UD0kQ_AUICigB&biw=1536&bih=759#imgrc=_
Keeping alpha transparency in mind, mask these over your images.
With all the things in correct proportion and sequence, You will get your old dusty image.

Which Imagemagick convert parameters should be used to create a GPG public key photo?

Per GPG guidelines, photo IDs should be about 240x288 pixels and 4k-6k in size. I used: convert -resize 240x240 -quality 75 original.jpg gpguid.jpg. However, the resulting file is still 17k. Specifically, I am curious what options I have before decreasing the quality level.
This is the command I settled on: convert -resize 240x240 -quality 55 -strip -sampling-factor 4:2:0 original.jpg gpguid.jpg.
The original command yielded a file that was 17,169 bytes. The -strip argument brought the size down to 10,226 bytes by removing profiles and comments. The -sampling-factor argument reduced the size to 8,315 bytes by cutting the chroma channel's resolution in half without affecting the luminance resolution. Finally, turning down the quality to 55 brought me within the recommended 6K.
ImageMagick has a feature that allows you to set a maximum output file size, and you may find you get on better letting it do that rather than arbitrarily reducing quality to the point that all photos are within the specified size - that way you should hopefully retain as much quality as possible:
convert input.jpg -strip -resize 240x240 -define jpeg:extent=6kb result.jpg
The above command will result in a file just under 6kB.
If you want a way to do something similar with Python, I wrote an answer that works pretty well here. It does a binary search for a JPEG quality that satisfies a maximum size requirement.

Using ImageMagick to add whitespace to images in bulk

I have a bunch of images that are rectangular and I need them to be square, i.e. 1000x1000, so I've decided to use ImageMagick to pad the sides of the image with the amount of whitespace necessary to make the image square.
I've found the code from the following link useful (see next paragraph). But this requires me to process each image individually, to set the filename and then the -thumbnail dimensions. How can I use this same process to process an entire folder?
Here's the code and the link to it:
http://imagemagick.org/Usage/thumbnails/#pad
convert -define jpeg:size=200x200 hatching_orig.jpg -thumbnail '100x100>' \
-background white -gravity center -extent 100x100 pad_extent.gif
It is not very clear from your question what you actually have (i.e. how big your images are? what format are they?), nor what you actually want (you only provide an example that doesn't do what you want. But I'll take your question at the face-vale of the title and hope you can work out anything missing from there.
If you want to do ImageMagick in bulk, you either need to use a loop in bash, like this:
#!/bin/bash
for f in *.jpg; do
convert "%f" ...
done
or use IM's mogrify command. That is quite a powerful command, so make a backup of your images before you even think of trying to use it.
Let's assume you want to place all JPEG images in the current directory onto a white 1000x1000 pixel background. You would do this:
mogrify -background white -gravity center -extent 1000x1000 *.jpg
Updated Answer
It should be possible to do the resizing and the white padding in a single ImageMagick command without needing to use SIPS as well, like this if you now want 1200x1200 square images padded with white:
mogrify -background white -gravity center -resize 1200x1200\> -extent 1200x1200 *.jpg

ImageMagick: Can I control which instance is used from a multi-resolution .ico file?

We have an in-house tool that does some operations on windows icon files. Turns out that it only really supports the type of .ico files that are generated by ImageMagick. Should be no big deal because we currently use ImageMagick anyway to generate sizes not supplied in the original image. My plan was to always use ImageMagick to generate images, even when the original .ico file contained an image with the correct resolution, to ensure the image was of the correct format.
So far, so good. However in practice this does not seem to work the way I expect it to. Specifically I'm after a 256x256 icon. The original file contains (I believe) a 256x256 version as it looks high res when viewed from the browser. However, the output file from ImageMagick is obviously a low-resolution one scaled up.
The command line I'm using is:
convert.exe orig.ico -background #FFFFFFFFFFFF0101 -compose Copy \
-gravity Center -scale 256x256! -depth 8 temp2.ico
Question: is there some better set of commands to use, which might start from the 256x256 icon?
Your orig.ico file probably contains multiple dimensions. They will also be stored in the output file. This means a dimension of 16x16 will be upscaled to 256x256 and that produces an ugly image. The 256x256 resolution is most likely the first dimension. You can see all the dimensions with the following command:
identify.exe orig.ico
With the command below you can get a specific dimension/image by specifying the index (starts at zero):
convert.exe orig.ico[0] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico
If the 256x256 dimension is the last image you should set the index to -1:
convert.exe orig.ico[-1] -background #FFFFFFFFFFFF0101 -compose Copy ^
-gravity Center -scale 256x256! -depth 8 temp2.ico

Resources