Progressive jpeg vs baseline jpegs - html

I have a web gallery where I display images which vary in file sizes and resolutions uploaded by users. Currently all the images are baseline. So I would like to know whether it would really have any significant impact if I converted them to progressive images. What are the advantages and tradeoffs on using progressive images.

The JPEG standard defines a variety of compression modes. Only three of these are in widespread use:
Baseline Sequential
Extended Sequential
Progressive
The only difference in the first to is in the number of tables allowed. Otherwise, they are encoded and decodes in exactly the same way.
JPEG divides images into Frames that are then divided into Scans. The modes above only permit one frame. The frame is the image. The scans are passes through the image data. A scan may be contain the data for one color component or it may be interleaved and contain data for multiple color components.
A grayscale sequential JPEG stream will have one scan.
A color sequential JPEG stream may have one or three scans.
JPEG takes 8x8 blocks of pixel data and applies the discrete cosine transform to that data. The 64 pixel data become 64 DCT coefficients. The first DCT coefficient is called the "DC" coefficient and the other 63 are called "AC" coefficients.
This is confusing terminology that drawing on the analogy with DC and AC current. The DC coefficient is analogous to the average pixel value of the block.
In sequential JPEG, the 64 coefficients in a block are encoded together (with the DC and AC coefficients encoded differently). In Progressive JPEG, the DC and the AC coefficients scans encode bitfields (of configurable size) within the coefficient. In theory, you could have a separate scan for each bit of each component.
Progressive JPEG is much more complicated to implement and use. If you are creating an encoder for sequential JPEG, you just need to give the caller the option to use interleaved or non-interleaved scans. For progressive JPEG your encoder needs a mechanism to the caller to determine how many scans and what bits should be encoded in each scan.
Progressive encoding can be slower than sequential because you have to make multiple passes over the data.
The speed issue in progressive decoding depends upon how it is done. If you decode the entire image at once, progressive is possibly marginally slower than sequential. If your decoder shows the image fading in as it processes the stream it will be much slower than sequential. Each time you update the display, you have to do the inverse DCT, upsampling, and color transformation.
On the other hand, it is possible to get much better compression using progressive JPEG with well-tuned scans.
There is no difference in quality between progressive and sequential
This book describes the processes:
https://www.amazon.com/Compressed-Image-File-Formats-JPEG/dp/0201604434/ref=asap_bc?ie=UTF8

The only difference is that progressive images are encoded in a way that allows browsers to display a rough preview of the image while it is still being downloaded, which becomes progressively better in quality until finally the download is complete. A baseline image will load from top to bottom, a progressive image will load from low-resolution to high-resolution.
For browsers which do not support progressive images, you won't see anything until the entire image has been loaded. (Nowadays all halfway modern browsers support progressive JPEGs.)
You can see animations of the difference in action, e.g. here: https://www.youtube.com/watch?v=TOc15-2apY0

Related

Is there a "law of diminishing returns" for converting images to Base64 as opposed to simply using the images themselves?

Say I have some icons on my site (32x32, 64x64, 128x128, etc.), then converting them to Base64 makes sense, right?
Now say I have some high resolution images that are 2MB, 3MB, 4MB, and greater that I am using on my site. Does it make sense to convert these larger images to Base64 or is it "smarter" to simply keep using them as .jpg/.png/.gif/etc.?
If there is such a "law", "rule of thumb", etc. what is the line in the sand?
EDIT: While this post was marked as a duplicate, the linked "original" is from over 10 years ago; browser technology, computers, and the web itself, has changed significantly since then. What would be the answer for today's technology?
The answer to the questions is yes, and it depends.
If we rephrase the question to: Does the law of diminishing returns apply to using base64 for embedding images in a page?
a) Yes, the law applies
b) It depends on: Image count and size, and your setup (ie HTTP (HTTP/2?) connection type, etc)
The reason being that more images require more connections imply more handshakes, unless you are using keep alive connections or HTTP/2 streaming. If the images are bigger and require more computing to convert from base64 back to binary (plus decompression), then the bandwidth saves come with CPU expense.
In general, if you have lots of images (icons, for example), you could embed as base64. But in that case you also have the following options:
a) Image Atlas: Converting all small images to a single image (one load) and showing only the portion that you need through the page.
b) Converting to alternative formats, such as fonts or SVG, and again rendering what you need. Example: Open Iconic.

Spritestage and multiple spritesheets

My team is currently working on a rather large Web application. We have switched from the flash platform to Html5 in hope for a one size fits all platform.
The UI, is mainly based on createjs, which I by the way really enjoy working with.
However we have now reached the maturity phase and started optimizing some of the animations, that doesn't run smoothly in especially IE.
The thing is that we have a around 1500 sprites (pngs & jpgs) which is drawn onto a stage. We only draw around 60 of them per frame.
They are rather large (up to 800x800 pixels), and the application engine can choose which 60 to show more or less randomly.
The images are packed in a zip file and unpacked in the browser and Html images are constructed by converting the binary data to a base64 encoded string, which is passed to the src property of an image.
So in each frame render a set of around
60 images are drawn to the stage. And this is for some reason slow.
I have therefore used some time to experiment with the Spritestage of createjs to take advantage of Webgl, but with only small improvements.
So now I'm considering to pack our sprites in a spritesheet, which results in many sheets because of the large amount of data.
My question is therefore:
Would spritestage gain any improvements if my sprites are spread across multiple sheets? According to the documentation only spritesheets with a single image are supported.
Best regards
/Mikkel Rasmussen
In general, spritesheets speed up rendering by decrease the number of draw call required by frame. Instead of say, using a different texture and render for every sprite, spritesheet implementations can draw multiple sprites with one render call, provided that the sprite sheet contains all the different individual sprite images. So to answer your question, you are unlikely to see performance gains if the sprites you want to draw are scattered on different sprite sheets.
Draw calls have significant overhead and it is generally a good idea to minimize them. 1500 individual draw calls would be pretty slow.
I dont know if it this is applicable to your situation but it is possible your bottleneck is not the number of draw calls you dispatch to GPU but you are doing too much overdraw since you mention your sprites are 800x800 each. If that is the case, try to render front to back with the depth test or stencil test turned on.

Using HTML5 canvas with SVG

I"m developing a diagramming application in HTML5/JavaScript. All drawing is done with SVG, using Raphael or qooxdoo SVG (not settled yet). The drawing area should use custom background image. The image is too big to be downloaded (several megabytes for 2560x1600 Retina resolution), that's why I construct it on the fly, composing it from tiles and applying bitmap effects. For that, I use HTML5 canvas. After that, the resulting background image has to be made accessible from SVG. To achieve that, I export a data URI from the canvas, and use <image xlink:href="data:image/png;base64,..."/> inside SVG.
This works for simple examples, but I'm a bit concerned about memory usage in production. Given that the image takes 12MB in memory (2560 * 1600 *3 bytes ber pixel), how much additional memory will be used? I suppose that at least some megabytes will be allocated to store base64-encoded PNG-compressed representation as data URI, and another 12 megabytes will go to the buffer for the SVG <image> element.
I wonder if there is a method to short-circuit this and to avoid redundant image encoding-decoding?
You can go around the base64 part with canvas.toBlob(callback) and window.URL.createObjectURL(). Other than that I don't think there is a place for you to further limit memory usage.
https://developer.mozilla.org/en-US/docs/Web/API/window.URL.createObjectURL
The toBlob() method can be shimmed on some browsers: https://github.com/blueimp/JavaScript-Canvas-to-Blob

Decoding a GIF question

For a personal project I'm creating a static gif decoder. Everything works well so far, except I'm having trouble understanding one concept from the specification:
This block is REQUIRED for an image.
Exactly one Image Descriptor must
be present per image in the Data Stream. An unlimited number of images
may be present per Data Stream.
(Spec)
Unlimited images per data stream? There can be more than 1? I'm assuming they don't mean an animated GIF because in the same specification they state, that they don't recommend gif's be used for animation.
I've read a lot of other sites documenting the gif format and they all state something similar. Heres another link:
There might be an unlimited number of images present in a GIF.
Any ideas?
GIF87a does not allow animation, but enables multiple images in GIF.
The idea was to decompose (for better total compression ratio) large picture into several rectangular subpictures drawn on a common canvas initially filled with background color. Every subpicture has its own x, y, width, height and palette. For example, if you are drawing astronomic picture: Earth and Moon, these two objects may be represented as two small subpictures on common large black canvas. It is not an animation: both subpictures are visible simultaneously.
But this beautiful idea was not supported by software (browsers, picture viewers, etc.), probably due to such non-standard approach.
Since GIF89a these subpictures were transformed into animation frames.
There can be more than one image present in a GIF file. Yes, GIF files can perform crude animation, but it's usually not pretty.

How much faster is it to use inline/base64 images for a web site than just linking to the hard file?

How much faster is it to use a base64/line to display images than opposed to simply linking to the hard file on the server?
url(data:image/png;base64,.......)
I haven't been able to find any type of performance metrics on this.
I have a few concerns:
You no longer gain the benefit of caching
Isn't a base64 A LOT larger in size than what a PNG/JPEG file size?
Let's define "faster" as in: the time it takes for a user to see a full rendered HTML web page
'Faster' is a hard thing to answer because there are many possible interpretations and situations:
Base64 encoding will expand the image by a third, which will increase bandwidth utilization. On the other hand, including it in the file will remove another GET round trip to the server. So, a pipe with great throughput but poor latency (such as a satellite internet connection) will likely load a page with inlined images faster than if you were using distinct image files. Even on my (rural, slow) DSL line, sites that require many round trips take a lot longer to load than those that are just relatively large but require only a few GETs.
If you do the base64 encoding from the source files with each request, you'll be using up more CPU, thrashing your data caches, etc, which might hurt your servers response time. (Of course you can always use memcached or such to resolve that problem).
Doing this will of course prevent most forms of caching, which could hurt a lot if the image is viewed often - say, a logo that is displayed on every page, which could normally be cached by the browser (or a proxy cache like squid or whatever) and requested once a month. It will also prevent the many many optimizations web servers have for serving static files using kernel APIs like sendfile(2).
Basically, doing this will help in certain situations, and hurt in others. You need to identify which situations are important to you before you can really figure out if this is a worthwhile trick for you.
I have done a comparison between two HTML pages containing 1800 one-pixel images.
The first page declares the images inline:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC">
In the second one, images reference an external file:
<img src="img/one-gray-px.png">
I found that when loading multiple times the same image, if it is declared inline, the browser performs a request for each image (I suppose it base64-decodes it one time per image), whereas in the other scenario, the image is requested once per document (see the comparison image below).
The document with inline images loads in about 250ms and the document with linked images does it in 30ms.
(Tested with Chromium 34)
The scenario of an HTML document with multiple instances of the same inline image doesn't make much sense a priori. However, I found that the plugin jquery lazyload defines an inline placeholder by default for all the "lazy" images, whose src attribute will be set to it. Then, if the document contains lots of lazy images, a situation like the one described above can happen.
You no longer gain the benefit of caching
Whether that matters would vary according to how much you depend on caching.
The other (perhaps more important) thing is that if there are many images, the browser won't get them simultaneously (i.e. in parallel), but only a few at a time -- so the protocol ends up being chatty. If there's some network end-to-end delay, then many images divided by a few images at a time multiplied by the end-to-end delay per image results in a noticeable time before the last image is loaded.
Isn't a base64 A LOT larger in size than what a PNG/JPEG file size?
The file format / image compression algorithm is the same, I take it, i.e. it's PNG.
Using Base-64, each 8-bit character represents 6-bits: therefore binary data is being decompressed by a ratio of 8-to-6, i.e. only about 35%.
How much faster is it
Define 'faster'. Do you mean HTTP performance (see below) or rendering performance?
You no longer gain the benefit of caching
Actually, if you're doing this in a CSS file it will still be cached. Of course, any changes to the CSS will invalidate the cache.
In some situations this could be used as a huge performance boost over many HTTP connections. I say some situations because you can likely take advantage of techniques like image sprites for most stuff, but it's always good to have another tool in your arsenal!