Reputation: 9040
I have a form with two images on it:
I have transloadit configured so that as soon as a new image is selected, transloadit creates a thumbnail, then pushes both the thumbnail and original image to Amazon S3.
To achieve this, in my transloadit account, I've created the following template:
{
"steps": {
"thumb": {
"use": ":original",
"robot": "/image/resize",
"width": 150,
"height": 150,
"resize_strategy": "pad",
"background": "#ffffff"
},
"store": {
"use": [
":original",
"thumb"
],
"robot": "/s3/store",
"key": "...",
"secret": "...",
"bucket": "www.mydomain.com",
"path": "staging/${file.id}.${file.ext}"
}
}
}
And my javascript is:
<script type="text/javascript">
var json_data = {};
$(function() {
// Hack to stop form submit from re-uploading files
// https://github.com/transloadit/jquery-sdk/issues/14
var bindTransloadit = function(form) {
form.transloadit({
wait: true,
modal: true,
triggerUploadOnFileSelection: false,
processZeroFiles: false,
autoSubmit: false,
params: {
auth: {
key: "..."
},
template_id: '...'
},
onStart: function(assembly) {
form.find('textarea[name=transloadit]').remove();
},
onUpload: function(upload) {
},
onCancel: function() { form.unbind('submit.transloadit'); },
onError: function(assembly) { form.unbind('submit.transloadit'); },
onSuccess: function(assembly) { form.unbind('submit.transloadit'); },
onResult: function(step, result)
{
json_data[step] = {
"basename": result.basename,
"field": result.field,
"name": result.name,
"url": result.url,
"ssl_url": result.ssl_url
};
var fld_data = '#fld_' + result.field + "_data";
$(fld_data).val(JSON.stringify(json_data));
if(step == "thumb")
{
$(fld_data).closest('.image-select').find('.thumbnail > img').attr('src', result.url);
}
}
});
};
$('#landing-page-form').on('change', 'input[type="file"]', function() {
var form = $(this).closest('form');
bindTransloadit(form);
form.trigger('submit.transloadit');
});
});
</script>
And some of my blade template/html, even though it might just confuse the issue:
@foreach ($fields as $name => $properties)
@if ($properties['type'] == "image")
<div class="form-group">
<label class="col-sm-2 control-label">{{ $properties['label'] }}</label>
<div class="col-sm-3">
<div class="image-select">
<!-- Thumbnail display -->
<div class="thumbnail">
<?PHP if(array_key_exists('thumb', $data[$name . "_data"])) { ?>
<img src="<?PHP echo($data[$name . "_data"]['thumb']['url']) ?>" alt="">
<?PHP } ?>
</div>
<!-- Width/Height display -->
<label>Width</label>: {{ $properties['width'] }} / <label>Height</label>: {{ $properties['height'] }}
<input type="file" name="{{ $name }}" id="fld_{{ $name }}" />
<textarea name="{{ $name }}_data" id="fld_{{ $name }}_data" class="hidden">{{ $data[$name . '_data']['json'] }}</textarea>
@if ($properties['help_block'] != "")
<span class="help-block m-b-none">{{ $properties['help_block'] }}</span>
@endif
</div>
</div>
</div>
<div class="hr-line-dashed"></div>
@endif
@endforeach
So far, all is good. However, now I'd like to have transloadit resize/crop both original images to the correct size. The primary image needs to be 300x150 pixels, and the secondary image needs to be 200x200 pixels. How do I do this?
Thanks!
Upvotes: 1
Views: 345
Reputation: 9040
Ah, I figured it out. Here's how I solved it:
1) Create resize template
In my transloadit account, I created this template. Most important is the resize_optimal step. This step contains width and height values of "10", but those values will be overwritten before the step is executed.
{
"steps": {
"thumb": {
"use": ":original",
"robot": "/image/resize",
"width": 150,
"height": 150,
"resize_strategy": "pad",
"background": "#ffffff"
},
"resize_optimal": {
"use": ":original",
"robot": "/image/resize",
"width": 10,
"height": 10,
"resize_strategy": "pad",
"background": "#ffffff"
},
"store": {
"use": [
":original",
"resize_optimal",
"thumb"
],
"robot": "/s3/store",
"key": "...",
"secret": "...",
"bucket": "...",
"path": "staging/${file.id}.${file.ext}"
}
}
}
2) Add width/height to data attributes
I modified both <input type="file"> tags to include the width and height that should be used for resizing the image as data attributes, like so:
<input type="file" name="primary_image" id="fld_primary_image" data-width="300" data-height="150" />
<input type="file" name="secondary_image" id="fld_secondary_image" data-width="200" data-height="200" />
3) Add global resize_options array
I added the following global array to my javascript:
var resize_options = {
width: 200,
height: 200
};
4) Override template width/height
In my transloadit binding, I overrode the resize_optimal width and height using the values of the resize_options array:
Before:
params: {
auth: {
key: "..."
},
template_id: '...'
},
After:
params: {
auth: {
key: "..."
},
template_id: '...',
steps: {
resize_optimal: {
width: resize_options.width,
height: resize_options.height
}
}
},
5) Populate resize_options
In my javascript, I was already running code whenever the file input changed. This is a great place to add code for keeping the resize_options array populated with the correct values:
Old:
$('#my-form').on('change', 'input[type="file"]', function() {
var form = $(this).closest('form');
bindTransloadit(form);
form.trigger('submit.transloadit');
});
New:
$('#my-form').on('change', 'input[type="file"]', function() {
var form = $(this).closest('form');
resize_options.width = $(this).data('width');
resize_options.height = $(this).data('height');
bindTransloadit(form);
form.trigger('submit.transloadit');
});
That's it! Now both images will be resized correctly.
Upvotes: 1