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

我有一个非常简单的问题,但我对导致问题的原因一无所知。 在我的一个应用程序中,我使用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

并使用jQuery('#cropper-box').append(''); 然后设置值。 我尝试了同样的事情,但是将图像src设置为1步而不是之后。

我试图在页面上放置占位符,并在单击按钮时更改源。 这是有效的,但是cropperarea保持图像的大小(300x180px或其他东西)并且不会变得更大。

//编辑:

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

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

//编辑2:

所以我已经为第一次和第二次尝试获取相同图像的来源。 正如在第一次尝试之前所述,图像将无法正确加载,第二次尝试它(仅当第二次尝试是相同的图像(!!)时)。

所选页面源显示1个差异,即首次尝试:

  

第二次尝试:

  

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

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

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

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

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

   

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

   

在我的情况下,我一直在使用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和其他人做过的思考;-)

创建“图像”对象并设置“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 

在这里尝试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 (eg IE 7.0). var tempImage = new Image(); tempImage.src = $origimg[0].src; $origimg.width(tempImage.width); $origimg.height(tempImage.height); } 

不要在onChange : updateCoords调用此函数

没有尝试,它将在手机上顺利运行。

您可以直接创建base64并将其显示为任何您想要的图像。

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

 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); } 

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

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

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

从那时起它一直运作良好。