Resize image which uses Jcrop
Asked Answered
C

5

5

I use the Jquery Jcrop for cropping my images. Now I'm implementing a slider for resizing the image. I want the cropping and resizing to happend on the same page.

I do it like this:

$(document).ready(function() {


    var img = $('#cropbox')[0]; // Get my img elem
    var orgwidth, orgheight;
    $("<img/>") // Make in memory copy of image to avoid css issues
        .attr("src", $(img).attr("src"))
        .load(function() {
            orgwidth = this.width;   // Note: $(this).width() will not
            orgheight = this.height; // work for in memory images.
        });

    $('#cropbox').Jcrop({
        onSelect: updateCoords
    });

    $("#imageslider").slider({
        value: 100,
        max: 100,
        min: 1,
        slide: function(event, ui) {
            //$('ul#grid li').css('font-size',ui.value+"px");
            resizeImage(orgwidth, orgheight);
        }
    });

});

And my simple resizeImage function:

function resizeImage(orgwidth, orgheight) {
    var value = $('#imageslider').slider('option', 'value');
    var width = orgwidth * (value / 100);
    var height = orgheight * (value / 100);
    $('#cropbox').width(width);
    $('#cropbox').height(height);
    $('#tester').val("org: "+orgwidth+" now: "+width);
}

The problem is that, as soon I turn on Jcrop I can't resize the image. How can I use both these functions at the same time?

Choirmaster answered 3/6, 2011 at 15:54 Comment(0)
C
6

I ended up destroying the jCrop while resizing and putting it back on after resize. Thanks anyway. Code:

        function resizeImage(orgwidth, orgheight) {
        jcrop_api.destroy();

        var value = $('#imageslider').slider('option', 'value');
        var width = orgwidth * (value / 100);
        var height = orgheight * (value / 100);
        $('#cropbox').width(width);
        $('#cropbox').height(height);
        $('#rw').val(width);
        $('#rh').val(height);

        initJcrop();

    }
Choirmaster answered 13/6, 2011 at 9:31 Comment(0)
L
3

I had the same task to accomplish: resize the image with a slider where jCrop is applied. There are some more elements you have to resize also that jCrop created, not only the image. I ended up patching the jCrop plugin and here is the patch for latest jCrop-0.9.10.

Patch your jCrop. If you don't know how to apply the patch, just put the resizeImage function to line 1578 of jCrop (unimified version ofcourse):

--- /home/dr0bz/Desktop/jquery.Jcrop.js
+++ /home/dr0bz/workspace/profile_tuning/js/lib/jquery.Jcrop.js
@@ -1573,6 +1573,15 @@
       ui: {
         holder: $div,
         selection: $sel
+      },
+      
+      resizeImage: function(width, height) {
+        boundx = width;
+        boundy = height;
+        $([$img2, $img, $div, $trk]).each(function(index, element)
+        {
+          element.width(width).height(height);
+        });
       }
     };

Get the jCrop API:

var jCropApi;
$('#photo').Jcrop({}, function()
{
  jCropApi = this;
});

Calc new height and width. If your are doing it with a slider, let the slider say return the new width of the image and you calculate new height with aspect ratio of the image:

var aspectRatio = width / height;
// newWidth returned by slider
var newHeight = Math.round(width / aspectRatio);
jCropApi.resizeImage(newWidth, newHeight);

There are some other points to keep an eye on. After each resize your should look that crop area is still in the viewport of the image. If you need i could post the complete source how i've done it for me: jCrop + jquery ui slider to resize the image.

Regards

Loment answered 16/10, 2012 at 11:54 Comment(2)
Using this as a base I've submitted a pull request here: github.com/tapmodo/Jcrop/pull/69Ambroseambrosi
Thank you! Working greatAncestor
C
1

What you can also do is make use of the setImage function of Jcrop, when the slider changes, call the setImage with the Jcrop api and set new width and height values like this:

var jcrop_api;

$('#cropbox').Jcrop({
    onSelect: updateCoords
}, function() {
    jcrop_api = this;
});

$("#imageslider").slider({
    value: 100,
    max: 100,
    min: 1,
    slide: function(event, ui) {
        var value = $('#imageslider').slider('option', 'value');
        var width = orgwidth * (value / 100);
        var height = orgheight * (value / 100);
        jcrop_api.setImage($(img).attr("src"), function() {
            this.setOptions({
                boxWidth: width,
                boxHeight: height
            });
        });
        $('#tester').val("org: "+orgwidth+" now: "+width);
    }
});

What I am not sure about this technique is if it is the best solution because everytime you call the setImage function, jcrop creates a new Image object.

Cordiform answered 22/10, 2013 at 21:23 Comment(0)
D
0

If what you want is that the resizing should be proportional, I don't think you need the slider (since it seems to be incompatible with jCrop). You could use jCrop and in the onChange event, ensure the proportionality (that is, implement the resizeImage function, modified).
That's what I think.

Doctor answered 4/6, 2011 at 10:29 Comment(0)
F
0

As an extension to Hermann Bier answer, i have added the jquery animation. The resizing looks way better when it's animated :)

Implemented in Jcrop version: jquery.Jcrop.js v0.9.12

Locate the code:

ui: {
    holder: $div,
    selection: $sel
  }

in jquery.Jcrop.js around line 1573 and replace it with:

ui: {
    holder: $div,
    selection: $sel
  },
  resizeImage: function(width, height) {
    animationsTid = 500;
    boundx = width;
    boundy = height;

    $($img2).animate({
        width: width, 
        height: height,
    }, { duration: animationsTid, queue: false });

    $($img).animate({
        width: width, 
        height: height,
    }, { duration: animationsTid, queue: false });

    $($div).animate({
        width: width, 
        height: height,
    }, { duration: animationsTid, queue: false });

    $($trk).animate({
        width: width, 
        height: height,
    }, { duration: animationsTid, queue: false });

    /*
    //Old way of resizing, but without animation
    $([$img2, $img, $div, $trk]).each(function(index, element){
      element.width(width).height(height);
    });
    */
  }

Call to the function will animate the resize. Feel free to delete the code between /* */ - I just kept it as an reference

Happy Coding :)

Flanch answered 16/12, 2013 at 21:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.