Vitaly Stanchits
Vitaly Stanchits

Reputation: 688

Plupload Thumbnail

I am working on a project and have to upload a file to s3. Here is my code:

config = $.extend(Photo.Plupload.config, config);
var uploader = new plupload.Uploader({
            runtimes:'flash,silverlight',
            browse_button:config.select_button,
            max_file_size:config.max_file_size,
            url:'http://' + Photo.Album.Form.bucket + '.s3.amazonaws.com/',
            flash_swf_url:'/assets/plupload/js/plupload.flash.swf',
            silverlight_xap_url:'/assets/plupload/js/plupload.silverlight.xap',
            init:{
                FilesAdded:function (up, files) {
                    /*plupload.each(files, function (file) {
                     if (up.files.length > 1) {
                     up.removeFile(file);
                     }
                     });
                     if (up.files.length >= 1) {
                     $('#' + config.select_button).fadeOut('slow');
                     }*/
                },
                FilesRemoved:function (up, files) {
                    /*if (up.files.length < 1) {
                     $('#' + config.select_button).fadeIn('slow');
                     }*/
                }
            },
            multi_selection:true,
            multipart:true,
            multipart_params:{
                'key':config.key + '/${filename}',
                'Filename':'${filename}', // adding this to keep consistency across the runtimes
                'acl':config.acl,
                'Content-Type':config.content_type,
                'success_action_status':'201',
                'AWSAccessKeyId':Photo.Album.Form.access_key_id,
                'policy':Photo.Album.Form.policy,
                'signature':Photo.Album.Form.signature
            },
            filters:[
                {
                    title:config.filter_title,
                    extensions:config.filter_extentions
                }
            ],
            file_data_name:'file'
        });

        // instantiates the uploader
        uploader.init();

        // shows the progress bar and kicks off uploading
        uploader.bind('FilesAdded', function (up, files) {
            // add pseudofile to the sheet
            console.log(files);
            $.each(files, function (index, value) {
                value.name = "thumb_" + value.name;
            });
            console.log(files);
            console.log(up);
            uploader.start();
        });

        // binds progress to progress bar
        uploader.bind('UploadProgress', function (up, file) {
            /*if (file.percent < 100) {
             $('#progress_bar .ui-progress').css('width', file.percent + '%');
             }
             else {
             $('#progress_bar .ui-progress').css('width', '100%');
             $('span.ui-label').text('Complete');
             }*/
        });

        // shows error object in the browser console (for now)
        uploader.bind('Error', function (up, error) {
            // unfortunately PLUpload gives some extremely vague
            // Flash error messages so you have to use WireShark
            // for debugging them (read the README)

            alert('Что-то непонятное произошло. Firebug в помощь.');
            console.log('Expand the error object below to see the error. Use WireShark to debug.');

            console.log(error);
        });

        // when file gets uploaded
        uploader.bind('FileUploaded', function (up, file) {
            //console.log(up);
            //console.log(file);
            // save file location in the database
            Photo.Album.Form.post(file)
            up.refresh();
        });

The code works. I upload a file to S3 and get a valid response that I send for the server to handle. Resizing images clientside also works.

What I am trying to do now is send a thumbnail to the server together with the original file. As far as I know, it is not possible to enter multiple resize-options in the plupload initializer. What can I do, so that not only the original file, but also its resized version gets sent to S3? Is it also possible to resize files directly on Amazon?

I'm trying to avoid the option of downloading the file and making my server resize and upload it again in different resolutions.

Thank you in advance.

Upvotes: 3

Views: 3298

Answers (2)

Kevin Borders
Kevin Borders

Reputation: 2992

A better solution is to trigger QueueChanged in the FileUploaded handler, and then call refresh. This will initiate the upload again for the same file and you can set a property that you read in the BeforeUpload handler to adjust the file size.

Warning #1: you should upload the thumbnail after the full-sized image, otherwise the full-sized image may have some buffer issues and get cut off.

Warning #2: This will only work if the bind call for FileUploaded happens after uploader.init(), otherwise the uploader's own handler for FileUploaded will overwrite file.status back to DONE after your handler.

uploader.bind('BeforeUpload', function(up, file) {
    if('thumb' in file)
      up.settings.resize = {width : 150, height : 150, quality : 100};
    else
      up.settings.resize = {width : 1600, height : 1600, quality : 100};
}

uploader.bind('FileUploaded', function(up, file) {
    if(!('thumb' in file)) {
        file.thumb = true;
        file.loaded = 0;
        file.percent = 0;
        file.status = plupload.QUEUED;
        up.trigger("QueueChanged");
        up.refresh();
    }
}

Upvotes: 3

Vitaly Stanchits
Vitaly Stanchits

Reputation: 688

Just in case someone is interested, I found a (probably temporary) solution to this issue.

        uploader.bind('UploadComplete', function (up, files) {
        console.log(uploader);
            // renew the file object
            if (config.complete == true) {
                // remove all files
                files = [];
                up.settings.multipart_params.key = config.key + '/${filename}';
                up.settings.resize = null;
            } else {
                up.settings.multipart_params.key = config.key + '/thumbs/${filename}';
                up.settings.resize = {width:100, height:100};
                $.each(files, function(index, value){
                    value.percent = 0;
                    value.status = 1;
                });
                config.complete = true;
                up.start();
            }
        });

So, 1. You make a semaphore variable "complete" initially false. 2. If not complete -> change the settings to generate thumbnails and restart plupload. Set complete to true. 3. If complete -> empty the file queue and reset the settings.

Ugly but does the job. I am still looking for a... prettier solution.

Upvotes: 1

Related Questions