0

I have a list of images which are in quite a big resolution, over 2000x1000 pixels. I want to display them on a page as thumbnails, but I don't want to actually/physically create thumbnails and store them on a server. Is there any unexpensive way to generate such images-thumbnails on the fly? Maybe using html5.

Dorion
  • 67
  • 1
  • 1
  • 6

4 Answers4

3
  • It's not clear to me where are the images.

is it like: file:///home/popcorn or http ://localhost:8080 for example

Please make sure what you want, before posting a question, what did you do? Where is your research..

In a Codepen I use a canvas to upload a big picture from the user to the server. And resize it before uploading.. So the resize is user side.

http://codepen.io/zoutepopcorn/pen/QvLxMp?editors=1010

Html

<input type="file" value=""><br/>
<label>Original Image</label><br/>
<img id="original-image" width="20px"><br/>
<br>
<img id="great-image"><br/>

Javascript

var input = document.getElementsByTagName('input')[0];

input.onclick = function () {
    this.value = null;
};

input.onchange = function(){
    resizeImageToSpecificWidth(200, function(dat) {
        console.log(dat);
        document.getElementById("great-image").src = dat;
  });
};

function resizeImageToSpecificWidth(max, cb) {
  var data;
  if (input.files && input.files[0]) {
    var reader = new FileReader();
    reader.onload = function(event) {
      var img = new Image();
      img.onload = function() {
        if (img.width > max) {
          var oc = document.createElement('canvas'), octx = oc.getContext('2d');
          oc.width = img.width;
          oc.height = img.height;
          octx.drawImage(img, 0, 0);
          if( img.width > img.height) {
            oc.height = (img.height / img.width) * max;
            oc.width = max;
          } else {
            oc.width = (img.width / img.height) * max;
            oc.height = max;
          }
          octx.drawImage(oc, 0, 0, oc.width, oc.height);          
          octx.drawImage(img, 0, 0, oc.width, oc.height);
          data = oc.toDataURL();
        } else {
          data = img.src;
        }
        cb(data);
      };
      img.src = event.target.result;
    };
    reader.readAsDataURL(input.files[0]);
  }
}
Johan Hoeksma
  • 2,863
  • 3
  • 23
  • 31
1

Depending on the server, there are different ways to resize the images before sending them to the browser. For PHP the answer is resize image in PHP.

If you want to do it in HTML5 (on the browser) you will still be sending the full size image so you will not get any benefit in bandwidth and download times. You can change the image size in the document by specifying it in the image tag attributes width and height or the style width and height. This will resize the image, but again the full size image is in memory in the browser which will consume a lot of memory if you have enough images displayed.

I don't believe HTML5 has any way of resizing the image to save memory, though you could use a javascript image editor library to resize the image after downloading and then removing the original from the document which would save on memory. However, this seems like the least effective method.

In my opinion, if you have a lot of images, the best way would be to convert the thumbnails and store them (sorry) but make your server handle all that automatically.

If you don't have a lot of images, just send the full size and take the performance hit in the browser.

Community
  • 1
  • 1
0

Creating a thumbnail with HTML5 (supposedly canvas) means that you have to download the image on the client first, resize it, and then display the image. There's no purpose in doing so, if you download the original large image anyway.

So, the only way I see it is to create a PHP file (or any server side language you use) which will generate thumbnails on the fly. I'll give you a PHP example.

(thumbnail.php)

<?php

// generates a thumbnail, if you only provide a width or a height value,
// it will keep the original image ratio
function output_thumbnail($source, $newWidth, $newHeight) {

    $type = pathinfo($source, PATHINFO_EXTENSION);
    if ($type == "png") {
        $image = imagecreatefrompng($source);
    } else {
        $image = imagecreatefromjpeg($source);
    }
    // get image dimensions
    $dimensions = getimagesize($source);

    $width = $dimensions[0];
    $height = $dimensions[1];

    if (!$newWidth && !$newHeight) return false;
    // if width or height is not set (but at least one is) calculate the other using ratio
    if (!$newWidth || !$newHeight) {
        $ratio = $width / $height;

        if ($newHeight) {
            $newWidth = $newHeight * $ratio;
        } else {
            $newHeight = $newWidth / $ratio;
        }
    }

    // create an empty image
    $resizedImage = imagecreatetruecolor($newWidth, $newHeight);
    // fill it with resized version of original image
    imagecopyresampled($resizedImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    // notify the browser that incoming response is an image
    header("Content-Type: image/jpeg");
    echo imagejpeg($resizedImage);

    // free the memory
    imagedestroy($image);
    imagedestroy($resizedImage);
}

output_thumbnail($_GET["image"], 500); // resize to 500 pixels in width

Now you can use it like this in your web page:

<img src="/thumbnail.php?image=images/large.jpg" />
Luka Kvavilashvili
  • 1,109
  • 8
  • 12
0

One possible solution for your case is using an API for uploading images, such as Cloudinary.

Cloudinary provides an API for uploading images to the cloud. The images are stored in the cloud with secure backups and revision history, utilizing Amazon's S3 service.

Cloudinary's Javascript library wraps Cloudinary's upload API and simplifies the integration.They also provide jQuery view helper methods for uploading directly from a browser to the cloud.

jQuery image upload library enables on the fly display of thumbnails of the uploaded images.

Here is a sample code that creates a 150x100 thumbnail of an uploaded image and updates an input field with the public ID of this image.

$('.cloudinary-fileupload').bind('cloudinarydone', function(e, data) {  
$('.preview').html(
$.cloudinary.image(data.result.public_id, 
  { format: data.result.format, version: data.result.version, 
    crop: 'fill', width: 150, height: 100 })
 );    
$('.image_public_id').val(data.result.public_id);    
 return true;
});
Gaby Weiss
  • 126
  • 4