jCrop(jQuery)有时无法加载图像/裁剪区域

时间:2011-05-09 12:59:02

标签: javascript jquery jcrop

我有一个非常简单的问题,但我对导致问题的原因一无所知。在我的一个应用程序中,我使用jCrop作为裁剪图像以适合横幅/标题等的小插件。这些步骤将采取:

1) Select an image (using CKFinder for this, CKFinder returns the image path to an input field)
2) Click a button to load the image
3) Crop the image
4) Save the image

在大约75%的情况下,一切都按计划进行,但是在另外25%的情况下,jCrop无法加载裁剪区域并将其留空。这是我正在使用的jQuery代码:

jQuery('#selectimg').live('click', function(e) { 
  e.preventDefault();
  var newsrc = jQuery('#img2').val();
  jQuery('#cropbox').attr('src', newsrc);
  var jcrop_api = jQuery.Jcrop('#cropbox', {
    boxWidth: 700, 
    boxHeight: 700,
    onSelect: updateCoords,
    onChange: updateCoords
  });
  //Some other JS code come's here for buttons (they work all the time)
});

我注意到当我把部分放在可裁剪区域中转换#cropbox的部分时,图像加载得很好,所以错误在于var = jcrop_api部分,但我开始慢慢思考没有解决方案...

这是我到目前为止所尝试的:

制作div <div id="cropper-box"></div>并使用jQuery('#cropper-box').append('<img src="" id="cropbox" />');然后设置值。我尝试了同样的事情,但是将图像src设置为1步而不是之后。

我尝试在页面<img src="placeholder.png" id="cropbox" />上放置占位符,然后点击按钮更改来源。这是有效的,但是cropperarea保持图像的大小(300x180px或其他)并且不会变得更大。

//编辑:

尝试更多信息向我展示了图像源正在被正确替换(!使用Firefox显示所选文本的来源),我仔细检查了URL,但这是一个正确的URL和一个工作图像。

在裁剪器所在的位置,有一个大约10x10像素的白点,裁剪器图标(加号)正在弹出......但如前所述:图像未显示。

//编辑2:

所以我为同一张图片拍摄了第一次和第二次尝试的来源。如第一次尝试之前所述,图像将无法正确加载,第二次尝试(仅当第二次尝试是相同的图像(!!)时)。

所选页面来源显示1个不同之处,即首先尝试:

<img style="position: absolute; width: 0px; height: 0px;" src="http://95.142.175.17/uploads/files/Desert.jpg">

第二次尝试:

<img style="position: absolute; width: 700px; height: 525px;" src="http://95.142.175.17/uploads/files/Desert.jpg">

我猜这是正在被jCrop取代的图像,但它是一个完整的谜语,为什么它在第一次放置0高度/宽度,第二次放置适当的尺寸。

6 个答案:

答案 0 :(得分:10)

好的伙计们,以防其他人遇到这个问题:

如果加载图像并对其应用jCrop的操作在彼此之后排队太快,则jCrop有点搞砸了。我仍然觉得奇怪的是,第二次尝试是完美的,但我认为这与缓存的图像维度有关,这些维度可以被页面的DOM或其​​他东西识别。

我想出的解决方案是创建一个函数,将#cropbox转换为jCrop区域,然后设置2秒间隔,只是为了给jCrop一些时间来识别图像及其尺寸,然后转换元素。

这是我使用的html的一部分(带有预加载器):

<div id="cropper-loading" style="display: none;"><img src="images/analytics/ajax-loader.gif" /></div>
<img id="cropbox" src="images/placeholder.png" style="display: none;" />

正如您所看到的那样,cropbox图像和cropper-loading div都是隐藏的,因为它们不是立即需要的。如果您愿意,可以显示占位符..然后使用此HTML表单:

<input name="image2" id="img2" type="text" readonly="readonly" onclick="openKCFinder(this)" value="click here to select an image" style="width: 285px;" />  <button class="button button-blue" type="submit" name="load" id="selectimg">Load Image in cropper</button>

在我的情况下,我一直在使用KCFinder加载图像(它是CKEditor的一部分,非常值得关注!),KCFinder处理上传,重命名等,选择后返回所选的图像路径(相对/绝对可配置) )到输入字段。

然后点击#selectimg时,会调用此代码:

jQuery('#selectimg').click(function(e) { 
    e.preventDefault();
    jQuery('#cropper-loading').css('display', 'block');

    var newsrc = jQuery('#img2').val();

    jQuery('#cropbox').attr('src', newsrc);
    jQuery('#img').val(newsrc);

    function createJcropArea() {
        jQuery('#cropper-loading').css('display', 'none');                                      
        jQuery('#cropbox').css('display', 'block');
        var jcrop_api = jQuery.Jcrop('#cropbox', {
            boxWidth: 700, 
            boxHeight: 700,
            onSelect: updateCoords,
            onChange: updateCoords
        });
        clearInterval(interval);
    }
    var interval = setInterval(createJcropArea, 2000);
});

首先,我阻止链接也会像往常一样(或按钮动作)被跟踪,然后显示加载div(这是我隐藏占位符图像的原因,否则它看起来会混乱)。

然后从输入字段加载图像位置并复制到另一个(#img),此字段用于处理图像(PHP使用#img的值加载此图像)。同时#cropbox src也被设置为新图像。

这是解决我问题的部分:

我没有直接激活jCrop,而是创建了一个函数:

1) hides the loading icon
2) displays the image
3) converts #cropbox into a jCrop area
4) clean the interval (otherwise it would loop un-ending)

在这个函数之后你可以看到,为了保存,我在转换jCrop区域之前花了2秒钟。

希望将来帮助任何人!

欢呼并感谢@vector和其他人的思考; - )

答案 1 :(得分:4)

创建“图像”对象并设置“src”属性不适用于您可以将图像视为已加载的图像。 此外,给出任何固定的超时间隔并不能保证图像已经加载。

相反,您应该为Image对象设置一个'onload'回调 - 然后初始化Jcrop对象:

var src = 'https://example.com/imgs/someimgtocrop.jpg'; 
var tmpImg = new Image();
tmpImg.onload = function() {
   //This is where you can safely create an image and a Jcrop Object
};
tmpImg.src = src; //Note that the 'src' attribute is only added to the Image Object after the 'onload' listener was defined

答案 2 :(得分:3)

在此处尝试repo上的边缘库:https://github.com/tapmodo/Jcrop

这应该可以解决您的问题。为解决您的问题而更改的行:

// Fix size of crop image.
// Necessary when crop image is within a hidden element when page is loaded.
if ($origimg[0].width != 0 && $origimg[0].height != 0) {
  // Obtain dimensions from contained img element.
  $origimg.width($origimg[0].width);
  $origimg.height($origimg[0].height);
} else {
  // Obtain dimensions from temporary image in case the original is not loaded yet (e.g. IE 7.0).
  var tempImage = new Image();
  tempImage.src = $origimg[0].src;
  $origimg.width(tempImage.width);
  $origimg.height(tempImage.height);
}

答案 3 :(得分:1)

请勿调用此函数onChange : updateCoords

不用尝试,它会在手机上流畅运行。

您可以直接创建base64,并在任何地方将其显示为图像。

答案 4 :(得分:0)

这是我奇怪但奇妙的解决方案:

if (obj.tagName == 'IMG') {
  var tempImage = new Image();
    tempImage.src = $origimg[0].src;
    $origimg.width(tempImage.width);
    $origimg.height(tempImage.height);
  if ($origimg[0].width > 1 && $origimg[0].height > 1) {
    $origimg.width($origimg[0].width);
    $origimg.height($origimg[0].height);
  } else {
    var tempImage = new Image();
    tempImage.src = $origimg[0].src;
    $origimg.width(tempImage.width);
    $origimg.height(tempImage.height);
     //console.log('error'+$origimg[0].width + $origimg[0].height);
  } 

答案 5 :(得分:0)

我知道这是旧的,但最近我的安装随机发生了。发现这是因为在jCrop初始化之前图像没有满载。

修复它所需要的只是将jCrop初始化内容包装在

$(window).on("load", function () { //jcrop stuff here });

自那以后它一直运作良好。