jquery-cropbox无法上传/显示中/高分辨率BLOB图像

时间:2018-01-06 20:23:12

标签: javascript jquery

裁剪和上传低分辨率图像时效果很好,但中等或大型文件根本不会上传。图像作为BLOB(工作)上传到本地服务器。较小和较大的图像在加载时显示控制台窗口中的BLOB,但实际只显示较低分辨率的图像。

我尝试过裁剪和上传多张图片,但我可以看到问题之间的唯一关联是超过10kb有问题。我也尝试使用base64编码,结果相同



window.onload = function() {
        var options =
        {
            imageBox: '.imageBox',
            thumbBox: '.thumbBox',
            spinner: '.spinner',
            imgSrc: 'avatar.png'
        }
        var cropper;
        document.querySelector('#file').addEventListener('change', function(){
            var reader = new FileReader();
            reader.onload = function(e) {
                options.imgSrc = e.target.result;
                cropper = new cropbox(options);
            }
            reader.readAsDataURL(this.files[0]);
            this.files = [];
        })
    
        document.querySelector('#btnCrop').addEventListener('click', function(){
            var img = cropper.getDataURL()
            document.querySelector('.cropped').innerHTML += '<img src="'+img+'">';
            $("#result").attr("value", img);
        })
        document.querySelector('#btnZoomIn').addEventListener('click', function(){
            cropper.zoomIn();
        })
        document.querySelector('#btnZoomOut').addEventListener('click', function(){
            cropper.zoomOut();
        })
    };
    /**
 * Created by ezgoing on 14/9/2014.
 */
'use strict';
var cropbox = function(options){
    var el = document.querySelector(options.imageBox),
    obj =
    {
        state : {},
        ratio : 1,
        options : options,
        imageBox : el,
        thumbBox : el.querySelector(options.thumbBox),
        spinner : el.querySelector(options.spinner),
        image : new Image(),
        getDataURL: function ()
        {
            var width = this.thumbBox.clientWidth,
                height = this.thumbBox.clientHeight,
                canvas = document.createElement("canvas"),
                dim = el.style.backgroundPosition.split(' '),
                size = el.style.backgroundSize.split(' '),
                dx = parseInt(dim[0]) - el.clientWidth/2 + width/2,
                dy = parseInt(dim[1]) - el.clientHeight/2 + height/2,
                dw = parseInt(size[0]),
                dh = parseInt(size[1]),
                sh = parseInt(this.image.height),
                sw = parseInt(this.image.width);

            canvas.width = width;
            canvas.height = height;
            var context = canvas.getContext("2d");
            context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
            var imageData = canvas.toDataURL('image/png');
            return imageData;
        },
        getBlob: function()
        {
            var imageData = this.getDataURL();
            var b64 = imageData.replace('data:image/png;base64,','');
            var binary = atob(b64);
            var array = [];
            for (var i = 0; i < binary.length; i++) {
                array.push(binary.charCodeAt(i));
            }
            return  new Blob([new Uint8Array(array)], {type: 'image/png'});
        },
        zoomIn: function ()
        {
            this.zoom(this.percent + Math.abs(this.minPercent - 1) / (this.options.zoom - 1 || 1));
            setBackground();
        },
        zoomOut: function ()
        {
            this.zoom(this.percent - Math.abs(this.minPercent - 1) / (this.options.zoom - 1 || 1));
            setBackground();
        }
    },
    attachEvent = function(node, event, cb)
    {
        if (node.attachEvent)
            node.attachEvent('on'+event, cb);
        else if (node.addEventListener)
            node.addEventListener(event, cb);
    },
    detachEvent = function(node, event, cb)
    {
        if(node.detachEvent) {
            node.detachEvent('on'+event, cb);
        }
        else if(node.removeEventListener) {
            node.removeEventListener(event, render);
        }
    },
    stopEvent = function (e) {
        if(window.event) e.cancelBubble = true;
        else e.stopImmediatePropagation();
    },
    setBackground = function()
    {
        var w =  parseInt(obj.image.width)*obj.ratio;
        var h =  parseInt(obj.image.height)*obj.ratio;

        var pw = (el.clientWidth - w) / 2;
        var ph = (el.clientHeight - h) / 2;

        el.setAttribute('style',
                'background-image: url(' + obj.image.src + '); ' +
                'background-size: ' + w +'px ' + h + 'px; ' +
                'background-position: ' + pw + 'px ' + ph + 'px; ' +
                'background-repeat: no-repeat');
    },
    imgMouseDown = function(e)
    {
        stopEvent(e);

        obj.state.dragable = true;
        obj.state.mouseX = e.clientX;
        obj.state.mouseY = e.clientY;
    },
    imgMouseMove = function(e)
    {
        stopEvent(e);

        if (obj.state.dragable)
        {
            var x = e.clientX - obj.state.mouseX;
            var y = e.clientY - obj.state.mouseY;

            var bg = el.style.backgroundPosition.split(' ');

            var bgX = x + parseInt(bg[0]);
            var bgY = y + parseInt(bg[1]);

            el.style.backgroundPosition = bgX +'px ' + bgY + 'px';

            obj.state.mouseX = e.clientX;
            obj.state.mouseY = e.clientY;
        }
    },
    imgMouseUp = function(e)
    {
        stopEvent(e);
        obj.state.dragable = false;
    },
    zoomImage = function(e)
    {
        var evt=window.event || e;
        var delta=evt.detail? evt.detail*(-120) : evt.wheelDelta;
        delta > -120 ? obj.ratio*=1.1 : obj.ratio*=0.9;
        setBackground();
    }

    obj.spinner.style.display = 'block';
    obj.image.onload = function() {
        obj.spinner.style.display = 'none';
        setBackground();

        attachEvent(el, 'mousedown', imgMouseDown);
        attachEvent(el, 'mousemove', imgMouseMove);
        attachEvent(document.body, 'mouseup', imgMouseUp);
        var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
        attachEvent(el, mousewheel, zoomImage);
    };
    obj.image.src = options.imgSrc;
    attachEvent(el, 'DOMNodeRemoved', function(){detachEvent(document.body, 'DOMNodeRemoved', imgMouseUp)});

    return obj;
};
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

当原始文件太大(无论是物理维度还是一般文件大小)时,有时会出现此问题,从而导致在Web服务器上达到上传大小限制(在php.ini中为upload_max_filesize或post_max_size)或导致内存耗尽缩略图创建期间在服务器上。 以下是检查并尝试解决此问题的一些步骤(在LAMP堆栈上,但Nginx和IIS中存在类似的日志和设置):

  1. 检查服务器本身的apache和php日志,以确定您是否达到内存限制或上传后大小限制。

  2. 如果您确实遇到内存耗尽错误,请尝试增加服务器的内存限制。请参阅PHP Memory exhausted

  3. 如果在突破内存限制后仍然遇到此错误,请检查裁剪/上传中断的一些中/大图像 - 确定每个图像的实际像素尺寸以及像素密度和/或dpi。如果其中一个非常大,您可能需要下载原始图像,以更合理的尺寸批量处理/重新保存,然后上传回服务器。

  4. 如果#3解决了问题,您可能希望将最大宽度/高度应用于应用程序中的图片上传字段,以防止内容管理员将来上传大量图片。

  5. 结合最大宽度&amp;高度选项,您可能还想查看设置插件以将缩略图保存为jpg格式,因为它比png压缩得更多。