重用FileReader时错误的宽度和高度

时间:2015-09-22 01:44:53

标签: javascript jquery css filereader jcrop

我目前正在开发一个简单的界面,允许用户上传图片,预览图片,然后将其裁剪为正方形。

我正在使用FileReader来预览图像,并使用jCrop进行裁剪。

以下是我正在使用的代码(其中的一部分):

    var jcrop = null;
    var reader = new FileReader();

    reader.onload = function (e) {

            $('#upload-picture-sample').attr('src', e.target.result).load(function(){
                var img = this;

                var imageWidth = img.width;
                var imageHeight = img.height;

                console.log(img.width+'-- WIDTH --'+$(this).width());
                console.log(img.height+'-- HEIGHT --'+$(this).height());

                if(imageWidth != imageHeight){

                    var selectArray = [];

                    if(imageWidth > imageHeight){
                        selectArray = [(imageWidth-imageHeight)/2, 0, (imageWidth-imageHeight)/2 + imageHeight, imageHeight];
                    }else{
                        selectArray = [0, (imageHeight - imageWidth)/2, imageWidth, (imageHeight - imageWidth)/2 + imageWidth];
                    }
                    if(!jcrop){
                        $('#upload-picture-sample').Jcrop({
                            aspectRatio: 1,
                            keySupport: false,
                            addClass: 'jcrop-centered',
                            setSelect: selectArray
                        }, function(){
                            jcrop = this;
                        });
                    }else{
                        jcrop.setImage(e.target.result);
                        jcrop.setSelect(selectArray);

                    }
                }
                $(this).unbind('load');
            });   
        }

    $('#upload-picture-file').change(function(){
        $('#upload-picture-send').removeClass('disabled');
        $('#upload-picture-error').hide();

        console.log('changed!');

        reader.readAsDataURL(this.files[0]);
    })

我认为唯一真正重要的部分是我计算宽度和高度时的部分。

为了说明问题,我正在上传:

1 / Picture1(600x450)

2 / Picture2(94x125)

再次

3 / Picture1(600x450)

enter image description here

第一次上传工作正常,第二次上线工作正常,但我想这比其他东西更幸运,因为高度被错误地计算为0。 第三次上传无效(大小未正确设置)。

这意味着庄稼区未正确显示。

关于css,我有这个:

#upload-picture-sample{
  display:block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 30px;
  max-height:125px;
  height:auto;
  width:auto;
  max-width:300px;
}

你知道如何解决我的问题吗?

更新:按照@initialxy的推荐添加setTimeout之后 enter image description here

所以它好多了,但是,第一张图片的尺寸与最后一张图片不同(它应该是,因为它是完全相同的图像) 感谢。

2 个答案:

答案 0 :(得分:1)

您的所有数字看起来都不一致。在第一个图像中,宽度最终为167,img.width,但jQuery为167。需要注意的一点是,jQuery获取computed styleimg.widthimg.height是设置所需宽度和高度的DOM属性。 (仅供参考,naturalWidthnaturalHeight,它们是只读的DOM属性,可以获得img的原始尺寸。)

  

它比其他东西更幸运

如果您的代码取决于运气,那么我们就遇到了问题。

看起来浏览器稍微过早地发出了加载事件,因此布局引擎还没有完成DOM的更新。 load只意味着数据被加载,并不一定意味着必须完成布局引擎。因此,尝试稍后在任务队列中将代码块排入加载函数内部。通过它,我的意思是将setTimeout(..., 0);中的所有内容包含在this中,因为它已经发生变化。

例如

$('#upload-picture-sample').attr('src', e.target.result).load(function(){
    var img = this;

    setTimeout(function() {
        var imageWidth = img.width;
        var imageHeight = img.height;

        console.log(img.width+'-- WIDTH --'+$(img).width());
        console.log(img.height+'-- HEIGHT --'+$(img).height());

        // TODO: Crop
        ...
    }, 0);

    $(this).unbind('load');
});

编辑:回应@ Vico的更新。看起来布局引擎这次已经解决了。让我们对这些数字进行一些观察。第一张图片的尺寸最初为600x450,但最终为167x125。这是有道理的,因为它由max-height: 125px; CSS属性调整大小。第二张图片的尺寸均小于max-widthmax-height,因此无法调整尺寸。第三张图片的尺寸为600x450,最终得到了这些尺寸,因此此时max-widthmax-height不再生效。这是为什么?也许jcrop与风格紧密相关并超越了你的风格。启动Chrome调试器,检查img元素并使用其JavaScript控制台来解决它。 (为了给你一个简短的回答,是的,jcrop确实搞定了样式并对元素应用了内联样式,这会覆盖你的风格。但是,嘿,使用调试器更有趣。)另外,我&#39 ;我不确定为什么右边的尺寸都以1440x514结束。您可以通过在调试器中进行调整来找到答案。

答案 1 :(得分:0)

有关详细信息,我建议所有潜在读者查看此问题: https://github.com/tapmodo/Jcrop/issues/46

解决方法很好。