matiasgali / guillotine Goto Github PK
View Code? Open in Web Editor NEWjQuery plugin to crop images within an area (fully responsive), allowing to drag (touch support), zoom and rotate.
Home Page: http://guillotine.js.org
jQuery plugin to crop images within an area (fully responsive), allowing to drag (touch support), zoom and rotate.
Home Page: http://guillotine.js.org
Sometimes when cropping an image to fit an aspect ratio you need to pad one side to get all of the image in the cropped area. With guillotine the most you can zoom out is to where the image is still filling the desired crop area. If there were a mode where you could zoom out more it would be more useful for some circumstances. For example you want to print a square picture on and 8x10 piece of paper and you are willing to either have white space on or cut the final product. The important thing is that you are able to print the comple image.
After initialzing the .guillotine-canvas has a width of 0% and doesn't change even when its zoomed.
When the guillotine is initialized with the init which contains 'scale' and 'angle', it is possible that te scale is multiplied:
Example init data:
{angle: 90, scale: 10, w: 7500, h: 7500}
Wrapper size: 750px * 750px
Width: 0.1
Height: 0.1
In the rotate method, the width and height will be smaller then 1, so the _fit method is called.
After this method, the scale will be set to 10.
When the rotate method is done, the _zoom method is called.
In this method: the factor will be multiplied by 10 again.
This will result in a scale of 100.
This leads to unexpected results.
I expect the scale to be 10, as specified.
I was using the guillotine plugin along with images that were received from a server using ajax and php. For some reason, on the initial load, the 'guillotine-canvas' has a width set to 0%. Upon reloading the page, though, the width is set to 100%.
Any ideas? Thanks in advance. Great plugin by the way!
After implementing Guillotine into my application, I found an issue when trying to add a scale value to the init options when adding the crop window to an image. It seems that the scale value is completely ignored and the default is used if the Width and Height parameters are specified. Whereas, if none are specified and it works from the default width and height values (400x300) then the scale is applied fine.
would be nice if I could change x, y, scale and angle programmatically. For instance:
picture.guillotine('setData', { scale: 1.4, angle: 270, x: 10, y: 20 });
Maybe I missed this: is there a way to restrict the user so they can only drag the image up and down (vertically) and not horizontally? I display my image at 100% width so allowing them to drag it left and right can cause the image to cut off.
Guillotine crop works great but it would be useful to have a checkered background in cases the image you're cropping has transparency!
Hello,
I tried cropping the original image with those val sent from your plugin. But the given values seems like it's not work. Here's the spec.
After I use these values to crop the image with php. The position (x,y) is not start on the correct point. I also tried change every values. But no luck. Can you please give an example of precise php to crop the image correctly?
I have tried your demo on iPhone in both Safari and Chrome. In Chrome the picture doesn't display and in Safari I can't zoom, rotate or anything.
When I set init parameters (such as initi { y:0 }), the library doesn't seem to set them properly.
So in _offset, I added a console.log('canvas style top is '+this.canvas.style.top); (line 268) to see when canvas style top is set. If you don't include an init call, canvas style top is only issued once. However, if you issue an init call, canvas style top is called twice. But only the first time, canvas.style.top is set to 0%; on the second run, it is set back to a negative value to center the image vertically.
So, it seems like the init parameters are properly set in _offset, but _offset is called a second time to overwrite whatever I set in init. Or is this just me?
Hello, thanks for perfect plugin.
I am not sure is it bug.
if it isn't - you may want add some extra info about this thing to readme.
// code to bug reproduce
var picture = $('#thepicture');
picture.guillotine('remove');//i need this in case of user pick another file
picture.guillotine({width: 400, height: 300});
picture.guillotine({eventOnChange: 'guillotinechange'});
picture.on('guillotinechange', function(ev, data, action){
//this callback doesn't work
});
picture.guillotine('fit');
//working code
var picture = $('#thepicture');
picture.guillotine('remove');//i need this in case of user pick another file
//event declaration should go before setting size or calling any method
picture.guillotine({eventOnChange: 'guillotinechange'});
picture.on('guillotinechange', function(ev, data, action){
//this callback works well
});
picture.guillotine({width: 400, height: 300});
picture.guillotine('fit');
Ubuntu 14.04 lts / chrome 39.0.2171.95 (64-bit) / jquery v1.11.1 / Guillotine v1.3.0
$('#thepicture') was loaded by FileReader.readAsDataURL
(i am working on image crop/preview before upload)
but i think it is'n matter
Hi, is there a reason for you not adding scroll controls for zooming actions?
Hi Thanks for the great plugin. But would like to know how I can crop an image based on output given my guillotine. I have used nodeJS gm module like below.
gm(req.files.file.path)
.rotate('white', parseFloat(body.angle))
.scale(body.mW * 1, body.mH * 1)
.crop(body.mW_W * 1, body.mH_W * 1, body.x * 1, body.y * 1)
.resize(parseInt(body.w), parseInt(body.h), "!")
.quality(1)
.setFormat("png")
.write(small, function (err) {
if (!err) {
console.log('Done!');
} else {
console.log(err);
console.log('error occurred');
}
});
But it does not seems working either ways. Could you please route me to correct path where I can get cropping correctly done.
Hi, I tried in my webpages and find a conflict when doing more than one picture crop/rotation.
The first one on my page works out fine, but the second is not showing the picture at all after doing picture.guillotine({width:xx,height:xx,eventOnChange: 'xxx'}).
Then I traced back, it happens to be this line in your code.
line 172:
guillotine = canvas.wrap(guillotine).parent();
UPDATE
Sorry, just checked, it was something conflicts with my css.
Guillotine by default lets you zoom in so far that the scale is >1. That forces Imagemagick or whatever you use to scale it, to basically upscale pixels that don't exist, making it at least a little pixellated. (WP image editor doesn't even let you upscale with the ->resize() command, giving "Could not calculate resized image dimensions".)
Can we have an option to show a warning or not permit scale >1 ?
It would be very useful if you could do the following:
var guillotineImage = $("#guillotine-image"),
currentZoom = guillotineImage.guillotine("getZoom");
guillotineImage.guillotine("setZoom", currentZoom * 0.5);
Hi, thanks for your great job with the plugin!
I ran into a problem when the plugin canvas element would get 0 size, even is it is created within onload of the image. It was happening in my particular case all the time, it does happen in your live example when it is loaded fresh for the first time, consequent refreshes work fine.
This is what I did to fix it:
Guillotine.prototype._wrap = function(element) {
var canvas, el, guillotine, height, img, paddingTop, width, _ref, _ref1, _ref2;
el = $(element);
if (el.prop('tagName') === 'IMG') {
img = document.createElement('img');
img.src = el.attr('src');
_ref = [img.width, img.height], width = _ref[0], height = _ref[1];
} else {
_ref1 = [el.width(), el.height()], width = _ref1[0], height = _ref1[1];
}
. . . . . .
Guillotine.prototype._wrap = function(element) {
var canvas, el, guillotine, height, img, paddingTop, width, _ref, _ref1, _ref2;
el = $(element);
if (el.prop('tagName') === 'IMG') {
// Replaced using locally created img element to determine dimensions with
// using naturalWidth/naturalHeight of the original image
// Removed creating of the temporary element as this is not needed.
_ref = [element.naturalWidth, element.naturalHeight], width = _ref[0], height = _ref[1];
} else {
_ref1 = [el.width(), el.height()], width = _ref1[0], height = _ref1[1];
}
. . . . . .
naturalWidth/naturalHeight are supported by all the browsers, except for IE* and lower. I am not sure if it is an issue for your library, since those browsers have 1.3% market share as of February.
Hi! Has anyone been able to implement this on Angular? Pls if so can you share a little sample? Thank you!
I noticed you closed the other discussion & I'm new to github so excuse me if you did get my first message.
Can you please clarify how this works because I'm merely looking at the demo & am very confused.
Excuse the third screenshot being in paint, the flipping thing kept screenshotting my wrong screen! :)
Anyway, image #1 shows the original image is size 2509 x 1673 px.
The size zoomed to is 1065 x 710
The width & height required is 400 x 300
The frame is 600 x 453px
So surely to get scale it should be...
1065 / 2509 = 0.424
double check with height: 710 / 1673 = 0.424
These are off a little after those decimals, but close enough.
Am I doing something wrong? I would hugely appreciate you explaining if so!
On the second screenshot you can see scale is listed as 0.2888.
It is my understanding that the width/height of 400x300 and the x/y positions are used ON the scaled image afterwards? This is hugely giving me grief, any help is really appreciated.
Hi,
I was wondering why do you use "stopImmediatePropagation" in _start method?
Thank you
Hi,
Fist of all, I would like to congratulate you for your work with guillotine : this is just an amazing plugin, so useful.
I just met one problem : I don't manage to init the guillotine with a different scale while I manage to set a default position or orientation (with x, y, or angle keys in init object but "scale" seems to not work).
First, is it simply possible to set this param ? And then, how do I have to set it ?
Thank you very much for you answers ;)
I'm storing Guillotine data on saving a page, and would like to return it to previous state upon returning (we don't actually crop the image on an edit page, so that editors can easily finetune the image positions if they choose to edit an existing page).
Would be nice if Guillotine supported it's own getData object when initing.
For example like this:
image.guillotine({
w : 500,
h : 400,
x : 100,
y : 50,
angle : 0,
scale: 1,
eventOnChange: 'guillotinechange'
});
Or simply image.guillotine({ data: dataobject, eventOnChange: 'guillotinechange' });
Hi,
First of all: great plugin!
I've done a lot of testing and debugging but can't find the problem.
I'm creating and edit photo form.
The users uploads the photo and can edit the photo before submitting the form.
The problem is that my div class="guillotine-canvas" is allways set to a square dimension, and that causes the distortion on the image.
Am I doing something wrong?
The html generated after the guillotine modifications is:
<div class="guillotine-window" style="width: 100%; height: auto; padding-top: 150%;">
<div class="guillotine-canvas" style="height: 100%; width: 150%; top: 0px; left: -25%;">
<img id="" ...>
</div>
</div>
Really appreciate your help,
Diogo Gomes
They are always 400 x 300?
I have spent too many hours and can't get this to work.
No matter what, even my demo, it always says 400x300.
Then there is a scale given that I can't figure out 0.472.
I can multiply it or divide any image width or length and it equals nothing that is relevant.
Please help me.
?
Hi
you do not have someone modified code that needs to be carried out by rotation of 5 degrees? I try it myself, but the picture is deformed. : / So only if someone has already been addressed.
thanks
Hey,
It is a fine plugin you have there. Do you think you can put together a code which would allow zooming in/out on touch events? Like panning?
hi,
how can i get the cropped image as base64 after the user is done with the editing?
How I am using this plugin:
When I change the picture the zoom factor becomes bigger. If I zoom in once is twice bigger than the last one.
This is the code I am using:
$('#upload').fileupload({
url : link,
singleFileUploads : true,
dataType : "json",
add : function(e, data) {
data.submit();
$('.loadingGIF').show('fade');
$('#logoSaved').hide('fade');
$('#orig_image').hide();
$('.alert-default').hide();
},
done : function(e, data) {
$('#saveYourLogo').removeClass('disabled');
$("#errorMessage").addClass("hidden");
$('.alert-default').show();
$('#orig_image').show();
$('.loadingGIF').hide();
$('#newImage').hide();
$('#AfterImageUpload').show('fade');
$('#saveYourLogo').show('fade');
$('#save_span').show('fade');
$('.cropbuttonscontainer').show('fade');
console.log("data:" + data);
//var json = JSON.parse(data.result);
//console.log("json:" + json);
var prop;
json = data.result;
//console.log("json temp:" + json["temp_img_id"]);
if (json.file == null) {
var ctx = "${pageContext.request.contextPath}";
$("#ok_width").val(json.ok_width);
$("#ok_height").val(json.ok_height);
$("#img_w").val(json.img_w);
$("#img_h").val(json.img_h);
var w = json.img_w, h = json.img_h;
if (w == h) {
$('#zoom_in').addClass('disabled');
$('#zoom_out').addClass('disabled');
$('#fit').addClass('disabled');
setTimeout(function() {
$('#saveYourLogo').click()
}, 1000);
} else {
$('#zoom_in').removeClass('disabled');
$('#zoom_out').removeClass('disabled');
$('#fit').removeClass('disabled');
}
$("#image_id").val(json.temp_img_id);
ok_width = json.ok_width;
ok_height = json.ok_height;
$("#orig_image").attr("src", "<c:url value="/resources/upload/temp_images/"/>" + json.temp_img_id + "_photo." + json.temp_img_ext);
$("#partial_temp_img_id").val(json.temp_img_id);
var picture = $('#orig_image');
//picture.guillotine('remove');
picture.on('load', function() {
// Initialize plugin (with custom event)
// picture.guillotine({eventOnChange: 'guillotinechange'});
//picture.guillotine({width: 200, height: 200});
picture.guillotine({
eventOnChange : 'guillotinechange',
width : ok_width,
height : ok_height,
zoomStep: 0.1
});
picture.guillotine('fit');
// Display inital data
var data = picture.guillotine('getData');
for ( var key in data) {
$('#' + key).html(data[key]);
}
// Bind button actions
$('#fit').click(function() {
picture.guillotine('fit');
});
$('#zoom_in').click(function() {
picture.guillotine('zoomIn');
});
$('#zoom_out').click(function() {
picture.guillotine('zoomOut');
});
// Update data on change
picture.on('guillotinechange', function(ev, data, action) {
data.scale = parseFloat(data.scale.toFixed(4));
//if scale is bigger than 0.9 dispable zoom in button
if (data.scale > 0.9) {
$('#zoom_in').addClass('disabled');
} else {
$('#zoom_in').removeClass('disabled');
}
for ( var k in data) {
$('#' + k).html(data[k]);
}
});
});
} else {
$("#errorMessage").text(json.file);
$("#errorMessage").removeClass("hidden");
}
}
});
$('.cropbuttonscontainer').css({
width : $('#max_w').val()
});
});
When I click on the zoom the page scroll to the top.
If the page is scrolled down. When I press zoom or something else from the controls the page this scroll me up to the top of the page. Any quick fix?
Is there a way for me to crop the image (like in Jcrop) along with being able to Zoom and rotate?
hi there i have put some thumbnail images on the same page and when you click on the thumbnail it swaps with the big image, i call the script again but unfortunetly it does not set it and crop doesnt work.
can you provide an example with multiple images or a method to restart the script ?
Hi Matias,
I've just downloaded and installed last guillotine version.
In my original html page :
and in my javascript :
var picture = jQuery('#edited-image');
picture.guillotine({width: 400, height: 300}) ;
jQuery('#rotate-left-button').click(function(){ picture.guillotine('rotateLeft'); });
jQuery('#zoom-in-button').click(function(){ picture.guillotine('zoomIn'); });
When I run my page, the picture appears in the right frame (400x300), and I can deplace it.
The original HTML has been transformed as :
And, I see that all javascript instructions are well executed, with break points in the mozilla debugger.
------>But the Guillotine controls bar doesnt appear !!
(jQueryguillotine.js is the 1.8.0)
What I did wrong ??
Thanks in advance
JPB
In Safari rotating images does not work. (Safari 8, OSX 10.10, latest jQuery, latest Guillotine)
The problem lies in how guillotine applies the css rotate property. In guillotine.js I found in line 346:
this.$el.css({
transform: "rotate(" + this.angle + "deg)",
});
which is not working under webkit. Instead there should be:
this.$el.css({
transform: "rotate(" + this.angle + "deg)",
"-webkit-transform": "rotate(" + this.angle + "deg)",
"-ms-transform": "rotate(" + this.angle + "deg)"
});
I am not sure which versions of jquery you support, but if you use 1.8.3 (just swap out 1.11 with this url http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js) there is an issue after you click and release the mouse. when you click, it triggers the drag, but after releasing, the drag is not released.
On Internet Explorer, the drag option is not working. I am trying to move it to reposition it and it doesn't work. The zoom in and out works.
This is how I use it:
var picture = $('#orig_image');
picture.on('load', function() {
// Initialize plugin (with custom event)
// picture.guillotine({eventOnChange: 'guillotinechange'});
//picture.guillotine({width: 200, height: 200});
picture.guillotine({
eventOnChange : 'guillotinechange',
width : ok_width,
height : ok_height,
zoomStep: 0.1
});
picture.guillotine('fit');
// Display inital data
var data = picture.guillotine('getData');
for ( var key in data) {
$('#' + key).html(data[key]);
}
// Bind button actions
$('#fit').click(function() {
picture.guillotine('fit');
});
$('#zoom_in').click(function() {
picture.guillotine('zoomIn');
});
$('#zoom_out').click(function() {
picture.guillotine('zoomOut');
});
// Update data on change
picture.on('guillotinechange', function(ev, data, action) {
data.scale = parseFloat(data.scale.toFixed(4));
//if scale is bigger than 0.9 disable zoom in button
if (data.scale > 0.9) {
$('#zoom_in').addClass('disabled');
} else {
$('#zoom_in').removeClass('disabled');
}
for ( var k in data) {
$('#' + k).html(data[k]);
}
});
});
} else {
$("#errorMessage").text(json.file);
$("#errorMessage").removeClass("hidden");
}
}
});
$('.cropbuttonscontainer').css({
width : $('#max_w').val()
});
});
I tried the demo also, and dragging is not working on that too.
I have Windows 8 Enterprise with IE 10.0.9200
I'm using the Aurelia framework and would like to know how could I use Guillotine with it.
Hi, I have a common occurring issue when I upload the image the default scale defaults 17.2083. Just wondering if anyone else has had this problem? Its happened a few times, unsure what is causing it.
Thanks.
I am trying to swap photos out on the fly, and when I use 'remove' and then instantiate a new instance, it does not work properly. Do you have any suggestions for this?
In case of rotating the image, after that fitting and finally reinitalising the guillotine with the same transformation pramteres, the library zooms in.
The sollution for the problem can be to switch the rotate and the zoom order at the _init function:
if ((angle = parseInt(o.angle))) { this._rotate(angle); } if ((scale = parseFloat(o.scale))) { this._zoom(scale); }
Just testing my application through IE8 (Guillotine v1.3.0), and it appears that 'scale' is being reported incorrectly.
I've got the following JS, using exactly the same image:
$image.guillotine({
width: 480,
height: 480,
onChange: function(event){
$form
.find('[name="image_data"]')
.val(JSON.stringify(event));
}
});
$image.guillotine('fit');
Then when I post the form data to my server, I get the following outputs:
[2015-01-14 12:51:03] staging.INFO: Image Data {"image_data":"[object] (stdClass: {\"scale\":2.962962962962963,\"angle\":0,\"x\":80,\"y\":0,\"w\":480,\"h\":480})"} []
[2015-01-14 12:51:09] staging.INFO: Image Data {"image_data":"[object] (stdClass: {\"scale\":0.625,\"angle\":0,\"x\":80,\"y\":0,\"w\":480,\"h\":480})"} []
Image below if you need it for testing purposes.
It would be nice if when you are cropping / moving the image, it would outline the full cropping range of the image (maybe with a border or something) that way you can easily see how much you can more the image around by, and know where abouts you are on the image.
Are you able to tag a 1.3.0 release? I'm pulling in from bower, and it'll only fetch up to 1.2.2 at the moment.
Thanks!
Is it possible to add this project to bower?
Again, great plugin! I am using the guillotine plugin on an img tag with an src that changes (the src is based on an ajax request that is dynamically changed by a user). After changing the src multiple times, the zoomStep changes significantly. I tried hardcoding in the zoomStep when initializing the plugin, but this still didn't fix the issue.
Another thing that could be related is that I only set up the plugin once, on the original img tag, and never again even after the src changes. I could post some code if that helps.
It seems that under ios, picking a photo that was taken in portrait mode messes up the scaling on display.
What probably happens is that ios rotates the display image (I think), since once cropped and uploaded to server the picture ends up 90 degrees off and squished...
You can see something is wrong in the crop view (the image is off scale).
Here are the example images.
Original ios (holding phone in portrait mode)
Display in guillotine squished under ios (holding phone in portrait mode)
Any ideas on how to fix / handle this ?
Thanks
Chris
Make a test but no was possible crop image in php by scale
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.