Today I learned that there are two ways to save JPEG files they are Baseline JPEG (standard) and Progressive JPEG (progressive). Both formats have the same size and image data, and their extensions are the same, the only difference is that they are displayed differently.

Differences between Baseline JPEG and Progressive JPEG

Baseline JPEG

This type of JPEG file is stored in a top-to-bottom scan, saving each line sequentially in the JPEG file. When this file is opened to display its contents, the data will be displayed in the order it was stored, line by line, from top to bottom, until all the data has been read, completing the display of the entire image. If the file is large or the network download speed is slow, then you will see the effect of the image being loaded line by line. There is no advantage to this format of JPEG, so Progressive JPEG is generally recommended.

Progressive JPEG

Unlike Baseline which scans once, Progressive JPEG files contain multiple scans, which are stored in the JPEG file in a smooth search. During file opening, a faint outline of the entire image is displayed first, and as the number of scans increases, the image becomes clearer and clearer. The main advantage of this format is that in case of slow networks, you can see the outline of the image to know roughly what is being loaded. You will notice this technique on some websites when opening larger images.

Progressive images bring the advantage of allowing users to see the general outline of the final image without having finished downloading the image, which can enhance the user experience to a certain extent. (It is still recommended to use the standard type for websites with waterfall stay)

In addition, the size of progressive images does not differ much from the basic image size, and sometimes it may be smaller than the basic image. The disadvantage of progressive images is that they eat up the user’s CPU and memory, but for today’s computers this amount of image computation is not a big deal.

How to save images as Progressive JPEG?

Having said that, here’s how to save images as or convert them to Progressive JPEG.

PhotoShop

In PS there is a “store as web format”, open it and select “continuous” is Progressive JPEG.

Linux

Detect if it is a progressive jpeg

1
identify -verbose filename.jpg | grep Interlace

If None is output, it is not a progressive jpeg; if Plane is output, it is a progressive jpeg.

Convert basic jpeg to progressive jpeg.

1
convert infile.jpg -interlace Plane outfile.jpg

PHP

Using the imageinterlace and [imagejpeg](https://www.php.net/manual/en/function. imagejpeg.php) functions we can easily solve the conversion problem.

1
2
3
4
5
6
<?php
    $im = imagecreatefromjpeg('pic.jpg');
    imageinterlace($im, 1);
    imagejpeg($im, './php_interlaced.jpg', 100);
    imagedestroy($im);
?>

Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import PIL
from exceptions import IOError

img = PIL.Image.open("c:\\users\\biaodianfu\\pictures\\in.jpg")
destination = "c:\\users\\biaodianfu\\pictures\\test.jpeg"
try:
    img.save(destination, "JPEG", quality=80, optimize=True, progressive=True)
except IOError:
    PIL.ImageFile.MAXBLOCK = img.size[0] * img.size[1]
    img.save(destination, "JPEG", quality=80, optimize=True, progressive=True)

jpegtran

1
jpegtran -copy none -progressive <inputfile> <outputfile>

C#

1
2
3
4
5
6
7
8
using (Image source = Image.FromFile(@"D:\temp\test2.jpg")) { 
    ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders().First(c => c.MimeType == "image/jpeg"); 
    EncoderParameters parameters = new EncoderParameters(3);
    parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
    parameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.ScanMethod, (int)EncoderValue.ScanMethodInterlaced);
    parameters.Param[2] = new EncoderParameter(System.Drawing.Imaging.Encoder.RenderMethod, (int)EncoderValue.RenderProgressive); 
    source.Save(@"D:\temp\saved.jpg", codec, parameters);
}