• js 预处理用户上传图片


    前几个月闲得无聊写得一段代码,没想最近刚好用上了,在硬盘里翻了半天找回来,还没好好整理直接用上了
    手机用户拍照上传的图片一般都在1M 到4M 之间,如果只是用作头像尺寸就可以缩小很多,1M甚至几M的图转换成几百K。

    <!doctype html>
    <html>
    <head>
    <title>test</title>
    <script src="js/zepto-master/src/zepto.min.js"></script>
    <script>

    /*****

    by cnblogs.com/ecalf

    **/

    var uploadImg = (function($){
        
        function fileUpLoader(config){
            if(typeof(config.field)=='string'){//input type=file
                config.field = document.getElementById(config.field);
            }
            if(typeof(config.viewPane)=='string'){//预览图
                config.viewPane = document.getElementById(config.viewPane);
            }
            if(typeof(config.uploadBtn)=='string'){//上传按钮
                config.uploadBtn = document.getElementById(config.uploadBtn);
            }
            
            this.afterSelectFile = config.afterSelectFile||function(){};
            
            this.maxSize = config.maxSize==undefined?4194304:(config.maxSize||0);//maxSize 0 不限制大小 
            
            this.field = config.field;
            this.viewPane = config.viewPane;
            this.uploadBtn = config.uploadBtn;
            if(config.uploadUrl){
                this.uploadUrl = config.uploadUrl;
            }
            if(typeof(config.afterUpload)=='function'){
                this.afterUpload = config.afterUpload;
            }
            if(Object(config.extParams)===config.extParams){
                this.extParams = config.extParams;
            }
            
            this.init();
        }
        fileUpLoader.prototype = {
            init:function(){
                this.domEvents();
                console.log('uploadfile init');
            },
            domEvents:function(){
                var host = this;
    
                if(host.field&&host.afterSelectFile){
                    $(host.field).on("change",function(e){
                        host.afterSelectFile&&host.afterSelectFile(this);
                    });
                }
                
                if(host.uploadBtn){
                    $(host.uploadBtn).on('click',function(){
                        host.upload();
                    });
                }
                
                
            },
            
            imgToDataURL:function(img,type,typecallback,frag){
                type = type||'image/png';
                var databack={
                        status:true,
                        dataURL:'',
                        callback:callback,
                        resolve:function(){
                            this.callback(this.dataURL);
                        }
                    }
                
                
                var trans = function(pic){//canvas.toDataURL,context.getImageData 不能读取跨域图片
                    pic.crossOrigin = "*";
                    var cvs = document.createElement("canvas");
                    document.body.appendChild(cvs);
                    var ctx = cvs.getContext('2d');
                    cvs.width = pic.width;
                    cvs.height = pic.height;
                    
                    console.log('img size:',pic.width+'px',pic.height+'px');
                    ctx.drawImage(pic,0,0,pic.width,pic.height);
                    var dataURL = cvs.toDataURL(type);
                    console.log('dataURL length:',dataURL.length)
                    cvs = null;
                    ctx = null;
                    
                    return dataURL;
                };
                
                if(!frag&&img.width&&img.height){ //img 加载完才能取出img的数据,如果在domReady 里面执行,图片未加载完会绘制出空白的 canvas
                    console.log('trans directly');
                    databack.dataURL = trans(img);
                    databack.resolve();
                    
                }else{//使用 图片的 natural size,img loaded后才能获得高宽
                    databack.status = false;
                    var pic = new Image();
                    pic.crossOrigin = "*";
                    pic.onload = function(e){
                        console.log('trans onload');
                        databack.dataURL = trans(e.target);
                        databack.status = true;
                        databack.resolve();
                        pic = null;
                    };
                    pic.src = img.src;
                }
                
                
                return databack;
            },
            
            dataURLToBlob:function(dataURL){
                console.log(dataURL.length)
                var type = dataURL.match(/data:(.+?);/);
                type = type?type[1]:'image/png';
                var dataContent = dataURL.replace(/^.+,/,'');
                dataContent = atob(dataContent);
                var dataCharCode = [];
                var i = 0;
                while(i<dataContent.length){
                    dataCharCode[i] = dataContent.charCodeAt(i);
                    i++;
                }
                var u8Arr = new Uint8Array(dataCharCode);
                return  new Blob([u8Arr],{type:type}); // you maybe use new BolbBuilder() in older browser, maybe canvas.toBlob() is better for image
            
            },
            
            readURL:function (input,callback) {//创建预览图
                input = input||this.field;
                if (input.files && input.files[0]) {
                    if(this.maxSize&&input.files[0].size > this.maxSize){
                        alert('文件大于'+(this.maxSize/(1024*1024))+'m,请重新上传');
                        return false;
                    }
                    
                    var reader = new FileReader();
                    reader.onload = function (e) {
                        callback&&callback(e.target.result);
                    };
                    var dataUrl = reader.readAsDataURL(input.files[0]);
                    reader = null;
                    return dataUrl;
                }
            },
            
            
        upload:function(fileConfig){
            var host = this;
            var formData = new FormData();
            var file,name,filename;
            if(!fileConfig){
                name = host.field.name;
                 file = host.field.files[0];
                 filename = host.field.value.split(/[/\]/).pop()||"temp.png";
            }else{
                name = fileConfig.name;
                 file = fileConfig.file;
                 filename = fileConfig.filename||"temp.png";
            }
           
            if(!file){
                console.log('no file');
            }
            
            formData.append(name,file,filename);
    
            if(Object(host.extParams)===host.extParams){
                $.each(host.extParams,function(k,v){
                    formData.append(k,v);
                });
            }
            
            $.ajax({
                    url: host.uploadUrl,
                    type: 'POST',
                    data: formData,
                    async: true,
                    dataType:'json',
                    cache: false,
                    contentType: false,
                    processData: false,
                    timeout:45000,
                    success: function (data,status, xhr) {
                        host.afterUpload&&host.afterUpload(data);
                        
                    },
                    error:function(xhr, errorType, error){
                        console.log(errorType, error);
                    },
                    complete:function(xhr, status){
                        console.log('post complete,status:',status);
                    }
                });
           
            }//end upload
        };
        
        
        return {
            init:function(config){
                return new fileUpLoader(config);
            }
        };
    
    })(Zepto);
    
    $(document).ready(function(){
        upload = uploadImg.init({
            field:'uploadimg',
            viewPane:'viewPane', 
            uploadBtn:'submitbtn',
            uploadUrl:'yourimguploadurl.jsp',
            maxSize:0,
            afterUpload:function(resp){ },
            extParams:{uid:12}
        });
        
        
        window.onload = function(){
            var img = document.querySelector("img");    
            upload.imgToDataURL(img,'image/jpeg',function(DataURL){
                var blob = upload.dataURLToBlob(DataURL);
                console.log(blob);
            },true);
        };
        
        
        
        
        $("#uploadimg").on("change",function(){
            var file = this.files[0];
            if(!file){ return; }
            
            upload.readURL(this,function(dataURL){
                upload.viewPane&&(upload.viewPane.src = dataURL);
                var img = new Image();
                img.onload = function(){
                    var img = document.querySelector("img");    
                    upload.imgToDataURL(img,'image/jpeg',function(dataURL){
                        var blob = upload.dataURLToBlob(dataURL);
                        console.log(blob);
                    },false);
                }
                img.src=dataURL;
                
            });
        });
            
        
        
        
    });
    
    </script>
    </head>
    <body>
    <div>
    <img id="viewPane" width="800" height="600"  src="img/1111.png" />
    <form id="testform">
    <!-- camera--照相机;camcorder--摄像机;microphone--录音 -->
    <input id="uploadimg" type="file" accept="image/*" capture="camera" />
    <input id="submitbtn" type="submit" />
    </form>
    
    </div>
    </body>
    </html>

     http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios

    ios  下 canvas 的 drawImage 存在扭曲 bug (似乎是像素过大时出现),修复方法如下

        
            /** 修复 ios 下 canvas drawImage 函数的 画面扭曲BUG
             * Detecting vertical squash in loaded image.
             * Fixes a bug which squash image vertically while drawing into canvas for some images.
             * This is a bug in iOS6 devices. This function from  CodeGo.net 
             * 
             */
            function detectVerticalSquash(img) {
             var iw = img.naturalWidth, ih = img.naturalHeight;
             var canvas = document.createElement('canvas');
             canvas.width = 1;
             canvas.height = ih;
             var ctx = canvas.getContext('2d');
             ctx.drawImage(img, 0, 0);
             var data = ctx.getImageData(0, 0, 1, ih).data;
             // search image edge pixel position in case it is squashed vertically.
             var sy = 0;
             var ey = ih;
             var py = ih;
             while (py > sy) {
              var alpha = data[(py - 1) * 4 + 3];
              if (alpha === 0) {
               ey = py;
              } else {
               sy = py;
              }
              py = (ey + sy) >> 1;
             }
             var ratio = (py / ih);
             return (ratio===0)?1:ratio;
            }
            /**
             * A replacement for context.drawImage
             * (args are for source and destination).
                     *  fixed:  set  height as   height/vertSquashRatio
             */
            function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
             var vertSquashRatio = detectVerticalSquash(img);
             ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
            }
            

    IOS 系统 safari 浏览器上开发 应注意的问题:

    https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW15

  • 相关阅读:
    iOS6和iOS7代码的适配(3)——坐标适配
    iOS6和iOS7代码的适配(2)——status bar
    iOS6和iOS7代码的适配(1)
    深入Blocks分析
    文字溢出加省略号
    点击图表每一部分触发某事件
    图表添加红线
    比较月份是否存在封装数据
    云上示范区项目总结
    页面之间通过地址栏传参
  • 原文地址:https://www.cnblogs.com/ecalf/p/4165263.html
Copyright © 2020-2023  润新知