Prevent full progressive jpeg download

So, let's say I have a large version of an image that only displays as a thumbnail. Is it possible to avoid creating a separate file for a thumbnail using progressive jpeg, stopping it from loading when a certain number of checks have been reached, and continuing to download only when the user decides to open it completely?

If so, how can I control image loading?

Thanks in advance.

+5
source share
2 answers

There are 2 approaches:

1. Client side load

Prerequisite

  • image server must support HTTP header range
    • eg. Range: bytes=0-1024 means that you request only the first 1024 bytes.
  • you need to know in advance how many bytes you want to request
    • you can specify the 1 / 8th full size if you click this value from the server side
    • therefore, the exact number of bytes must be known on the client side
  • if Range invalid or not supported, then the server will return the whole image, which is a good natural "backup"

Cross domain requests : if html and images are in different domains

  • Access-Control-Allow-Headers: "range" must be set

Apache .htaccess example on image server :

 <IfModule mod_headers.c> Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Headers: "range" </IfModule> 
  • If the browser does not fulfill the request due to incorrect CROS settings, the code is returned back to set the data-src attribute to the src attribute

Overview

  • AJAX request image request
    • set the Range header of the AJAX request to the number of bytes you want to return
    • set mimeType to plaintext (so that we can encode it base64 later)
  • Base64 encodes the data and sets the src attribute of the image ( <img src="data:image/jpeg;base64,..."> )
    • Beware of large images, this can be quite heavy on the client.
  • If the src attribute is not configured for any reason (for example, incorrect CROS settings), then release to set the data-src attribute to the src attribute

Code

This is built on gaetanoM's amazing answer here: Get the image using jQuery.ajax () and decode it to base64

 // for each img, which has data-src and data-bytes attributes $('img[data-src][data-bytes]').each(function(i,e){ $.ajax({ url: $(e).data('src'), // url of image type: 'GET', headers: { 'Range':'bytes=0-'+$(e).data('bytes') // Range header, eg. Range: bytes=0-1024 }, mimeType: "text/plain; charset=x-user-defined" }).done(function( data, textStatus, jqXHR ) { $(e).attr('src', 'data:image/jpeg;base64,' + base64encode(data)); // on success we set the base64 encoded data to the image src attribute }).always(function(){ // if setting the src failed for whatever reason, we fall back to set the data-src attribute to src attribute if(!$(e).attr('src')) $(e).attr('src', $(e).data('src')); }); }); function base64encode(str) { var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var out = "", i = 0, len = str.length, c1, c2, c3; while (i < len) { c1 = str.charCodeAt(i++) & 0xff; if (i == len) { out += CHARS.charAt(c1 >> 2); out += CHARS.charAt((c1 & 0x3) << 4); out += "=="; break; } c2 = str.charCodeAt(i++); if (i == len) { out += CHARS.charAt(c1 >> 2); out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)); out += CHARS.charAt((c2 & 0xF) << 2); out += "="; break; } c3 = str.charCodeAt(i++); out += CHARS.charAt(c1 >> 2); out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)); out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)); out += CHARS.charAt(c3 & 0x3F); } return out; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!-- total filesize is 35 933 bytes --> <img data-src="http://shoepimper.com/doklist.com-logo.jpg" data-bytes="1900"> <img data-src="http://shoepimper.com/doklist.com-logo.jpg" data-bytes="2500"> <img data-src="http://shoepimper.com/doklist.com-logo.jpg" data-bytes="5600"> <!-- if data-bytes are erroneous the server will return the whole image --> <img data-src="http://shoepimper.com/doklist.com-logo.jpg" data-bytes="error"> <!-- if CROS fails, then it falls back to set the data-src attribute to the src attribute --> <img data-src="/img/cc662e438a01a82ff56993222d9c1103.jpg" data-bytes="error"> 

2. Serious server side

By interacting with the ProgressiveMonkey comment, you can easily crop image data using php or any other server-side programming language.

Overview

Server code

 <?php $div = isset($_GET['div']) && intval($_GET['div'])>1 ? intval($_GET['div']) : 1; // what fraction of the image shall we return $img = 'doklist.com-logo.jpg'; $size = round(filesize($img) / $div); // calculating the size in bytes what we return // setting the headers header("Content-Type: image/jpeg"); header("Content-Length: $size"); $fp = fopen($img, 'r'); echo fread($fp, $size); // returning the necessary amount of bytes fclose($fp); ?> 

<strong> Examples

Please see here one of the logos of our site ( Doklist.com )

Please feel free to play along with this url div parameter (also note that my test server may not handle increased traffic): http://shoepimper.com/progressive-thumb.php?div=14

Only reading the 1 / 24th file and returning it as a whole image: <img src="http://shoepimper.com/progressive-thumb.php?div=24"> enter image description here

Reading 1 / 14th of the image: <img src="http://shoepimper.com/progressive-thumb.php?div=14"> enter image description here

Reading 1 / 6th of the image: <img src="http://shoepimper.com/progressive-thumb.php?div=6"> enter image description here

Read the whole image (1 / 1st) <img src="http://shoepimper.com/progressive-thumb.php?div=1"> enter image description here

If you need help deciding whether an image will be progressively encoded or not, use this: http://codepen.io/sergejmueller/full/GJKwv

If you do not have direct access to images, you should use a proxy server, that is, the structure of the code itself does not really change, you simply "open" the remote file.

+6
source

It would be possible. You just need to change the decoder to do this.

You can control the download as long as you have access to the data stream.

+1
source

Source: https://habr.com/ru/post/1235275/


All Articles