Jcrop 不刷新新选择的图像

Posted

技术标签:

【中文标题】Jcrop 不刷新新选择的图像【英文标题】:Jcrop does not refresh newly selected image 【发布时间】:2019-09-20 15:18:59 【问题描述】:

我设计了一个表单,让用户可以在他们的计算机上选择一张图片,裁剪它,最后上传为个人资料图片。我使用JCrop 裁剪照片。经过一番努力,现在一切似乎都很好,除了如果用户改变主意并想浏览第二张图片,我的表单上的图片不会被替换。我确实替换了“预览”图像的 src 属性,但似乎以某种方式JCrop still stores the previous image 并且这以某种方式“覆盖”了新图像。我尝试使用 JCrop setImage 方法来替换图像,但它似乎不起作用。有关如何解决此问题的任何提示?请参阅下面的代码示例。

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;
    
  

【问题讨论】:

【参考方案1】:

我创建了一个这样的包装器

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

并清理 de wrapper 并重新创建 de img 以重新加载新图像

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

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

然后创建一个新的 JCrop

img.Jcrop(....)

【讨论】:

以上是关于Jcrop 不刷新新选择的图像的主要内容,如果未能解决你的问题,请参考以下文章

输入文件在 JCrop 中显示实时选择的图像

如果调整图像大小,Jcrop 问题 - Jquery

裁剪图像并将图像保存为圆形 JCrop

如何在临时图像上使用 jCrop?

Jcrop 图像干预 Laravel 5

Jcrop 图像在预览中无法正确显示