0

I work a form that would let users to select an image on their computer, crop it and finally upload as profile image. I use JCrop to crop the photo. After a lot of struggles, now everything seems to work fine, except that if the user changes its mind and would like to browse in a second image, the image is not replaced on my form. I do replace the src attribute of the 'preview' image, but it seems that somehow JCrop still stores the previous image and this somehow "covers" the new image. I tried to use the JCrop setImage method to replace the image, but it does not seem to work. Any hints on how to fix this? Please see the code samples below.

var currentFile;
var file;
var options;

// convert bytes into friendly format
function bytesToSize(bytes) {
    var sizes = ['Bytes', 'KB', 'MB'];
    if (bytes == 0) return 'n/a';
    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
    return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};

// check for selected crop region
function checkForm() {
    if (parseInt($('#w').val())) return true;
    jQuery('.error').html('Please select a crop region and then press Upload').show();
    return false;
};

// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
    jQuery('#x1').val(e.x);
    jQuery('#y1').val(e.y);
    jQuery('#x2').val(e.x2);
    jQuery('#y2').val(e.y2);
    jQuery('#w').val(e.w);
    jQuery('#h').val(e.h);
};

// clear info by cropping (onRelease event handler)
function clearInfo() {
    jQuery('.info #w').val('');
    jQuery('.info #h').val('');
};

function fileSelectHandler(evt) {

    // hide all errors
    jQuery('.error').hide();

    // grabbing image
    evt.preventDefault()
    var target = evt.target
    file = target && target.files && target.files[0]

    if (!file) {
        jQuery('.error').html('Image not found.').show();
        jQuery('#main_photo').val('');
        return;
    }

    var oFile = target.files[0];

    // check for image type (jpg is allowed)
    var rFilter = /^(image\/jpeg)$/i;
    if (! rFilter.test(oFile.type)) {
        jQuery('.error').html('Please select a valid image file (jpg)').show();
        jQuery('#main_photo').val('');
        return;
    }

    // check for file size
    if (oFile.size > 5 * 1024 * 1024) {
        jQuery('.error').html('You have selected too big file (max: 5 MB), please select a one smaller image file').show();
        jQuery('#main_photo').val('');
        return;
    }

    //setting options for image loader
    options = {
        orientation: true, 
        maxWidth: 400
    }

    // preview element
    var oImage = document.getElementById('preview');

    // adding onload event handler to initialize JCrop
    oImage.onload = function () { 

        // Create variables (in this scope) to hold the Jcrop API and image size
        var jcrop_api, boundx, boundy;

        console.log(oImage);


        // destroy Jcrop if it is existed
        if (typeof jcrop_api != 'undefined') {
            jcrop_api.destroy();
            jcrop_api = null;         
        }

        // initialize Jcrop
        jQuery('#preview').Jcrop({
            minSize: [32, 32], // min crop size
            aspectRatio : 200/250, // keep aspect ratio 1:1
            bgFade: true, // use fade effect
            bgOpacity: .3, // fade opacity
            trueSize: [oImage.naturalWidth,oImage.naturalHeight], 
            onChange: updateInfo,
            onSelect: updateInfo,
            onRelease: clearInfo
        }, function(){

            // use the Jcrop API to get the real image size
            var bounds = this.getBounds();
            boundx = bounds[0];
            boundy = bounds[1];

            // Store the Jcrop API in the jcrop_api variable
            jcrop_api = this;
            console.log(jQuery('#preview').attr('src'));
            jcrop_api.setImage(jQuery('#preview').attr('src')); 
        });
    };


    displayImage(file, options);


}

  /**
   * Updates the results view
   *
   * @param {*} img Image or canvas element
   * @param {object} [data] Meta data object
   */
  function updateResults(img, data) {
    var fileName = currentFile.name
    var href = img.src
    var dataURLStart
    var content
    if (!(img.src || img instanceof HTMLCanvasElement)) {
      content = jQuery('<span>Loading image file failed</span>')
    } else {
      if (!href) {
        href = img.toDataURL(currentFile.type + 'REMOVEME')
        // Check if file type is supported for the dataURL export:
        dataURLStart = 'data:' + currentFile.type
        if (href.slice(0, dataURLStart.length) !== dataURLStart) {
          fileName = fileName.replace(/\.\w+$/, '.png')
        }
      }
      content = jQuery('<a target="_blank">')
        .append(img)
        .attr('download', fileName)
        .attr('href', href)
    }

    jQuery('#preview').attr("src", href);
  }




  /**
   * Displays the image
   *
   * @param {File|Blob|string} file File or Blob object or image URL
   * @param {object} [options] Options object
   */
  function displayImage(file, options) {
    currentFile = file
    if (!loadImage(file, updateResults, options)) {
        jQuery('.error').html('Incompatible browser. Image cannot be displayed.').show();
        jQuery('#main_photo').val('');
        return;
    }
  }
wanderlusted
  • 187
  • 13

1 Answers1

1

I created a wrapper like this

<div id="wrapper_img">
   <img id="img">
</div>

and clean de wrapper and recreate de img to reload new image

$('#wrapper_img').empty();

var img = $('<img id="img">');
img.attr('src', 'my_image.png');
img.appendTo('#wrapper_img');

after that y create a new JCrop

img.Jcrop({....})