js前端图片处理例子

首先需要了解几个api

FileReader

FileReader主要用于将文件内容读入内存,通过一系列异步接口,可以在主线程中访问本地文件。

<table> <tr> <th>方法定义</th> <th>描述</th> </tr> <tr> <td>abort():void</td> <td>终止文件读取操作</td> </tr> <tr> <td>readAsArrayBuffer(file):void</td> <td>异步按字节读取文件内容,结果用ArrayBuffer对象表示</td> </tr> <tr> <td>readAsBinaryString(file):void</td> <td>异步按字节读取文件内容,结果为文件的二进制串</td> </tr> <tr> <td>readAsDataURL(file):void</td> <td>异步读取文件内容,结果用data:url的字符串形式表示</td> </tr> <tr> <td>readAsText(file,encoding):void</td> <td>异步按字符读取文件内容,结果用字符串形式表示</td> </tr> </table>

事件

<table> <thead> <tr> <th>事件名称</th> <th>描述</th> </tr> </thead> <tbody> <tr> <td>onabort</td> <td>当读取操作被中止时调用</td> </tr> <tr> <td>onerror</td> <td>当读取操作发生错误时调用</td> </tr> <tr> <td>onload</td> <td>当读取操作成功完成时调用</td> </tr> <tr> <td>onloadend</td> <td>当读取操作完成时调用,不管是成功还是失败</td> </tr> <tr> <td>onloadstart</td> <td>当读取操作将要开始之前调用</td> </tr> <tr> <td>onprogress</td> <td>在读取数据过程中周期性调用</td> </tr> </tbody> </table>

画布API

  • 创建画布 var canvas = document.createElement('canvas');
  • 在画布上绘图的环境。var context = canvas.getContext('2d')
  • 填充一张图片到画布上 context.drawImage(img,0,0,canvas.width,img.height/ratio);
  • 将画布转为blob canvas.toBolob(callback)

下载图片

html5中在a链接中加入了download属性时,会强制触发下载操作,且自动命名文件为download属性的值。我们定义一个鼠标事件并初始化,然后在a链接上绑定事件,并触发这个鼠标事件,等于手动点击了这个a标签,起到了下载的功能

模拟创建鼠标事件对象的方法
  • 新建一个鼠标事件 let event = document.createEvent('MouseEvents')
  • 初始化鼠标事件 event.initMouseEvent('click',false,false,window,0,0,0,0,0,false,false,false,false,0,null)
  • 在节点上绑定事件,并触发这个事件 element.dispatchEvent(event)

创建鼠标事件对象的方法createEvent('MouseEvents'),返回的对象的方法initMouseEvent(),接收15个信息:

1. type(字符串):事件类型如“click”;
2. bubble(布尔值):是否冒泡;
3. cancelable(布尔值):是否可取消;
4. view(AbstractView):与事件关联的视图,一般为document.defaultView;
5. detail(整数):一般为0,一般只有事件处理程序使用;
6. screenX(整数):事件相对于屏幕的X坐标;
7. screenY(整数);
8. clientX(整数):事件相对于视口的X坐标;
9. clientY(整数);
10. ctrlKey(布尔值):是否按下了Ctrl键,默认为false;
11. altKey(布尔值);
12. shiftKey(布尔值);
13. metaKey(布尔值);
14. button(整数):表示按下了哪个鼠标键,默认为0;
15. relatedTarget(对象):表示与事件相关的对象。一般只有在模拟mouseover与mouseout时使用。

另外,建议使用构造函数MouseEvent来初始化创建一个事件

var evt = new MouseEvent("click", {
    bubbles: true,
    cancelable: true,
    view: window
});
模拟创建键盘事件
  • 新建一个键盘事件 var event = document.createEvent("KeyboardEvent");
  • 初始化这个键盘事件 event.initKeyboardEvent("keydown",true,true,document.defaultView,"a",0,"Shift",0);
  • 在元素上模拟触发这个键盘事件 element.dispatchEvent(event);

event.initKeyboardEvent 接受以下参数:

typeArg(字符串):要触发的事件类型,可选(keydown, keypress, or keyup)
canBubbleArg(布尔值):表示事件是否应该冒泡;
cancelableArg(布尔值):是否可以取消;
viewArg(AbstractView):与事件关联的视图。一般为document.defaultView;
keyArg(布尔值):表示按下的键的键码;
locationArg(整数):表示按下哪里的键。0为主键盘;1为左;2为右;3为数字键盘;4为虚拟键盘;5为手柄;
modifiersListArg(字符串):空格分隔的修改键列表,如“shift”;
repeatArg(整数):在一行中按下了多少次这个键;
文件上传

FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据 let formData = new FormData();

  • 添加字段 formData.append("username", "Groucho")
base64转File
function base64ToFile(base64,filename) {
    var arr = base64.split(','),mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),n=bstr.length,u8arr=new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new File([u8arr],filename,{type:mime})
}
base64转Blob
function base64ToBlob(base64){
    var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
    }
    return new Blob([u8arr], { type: mime });
}
XMLHttpRequest
  • 获取一个XMLHttpRequest对象 var xhr = new XMLHttpRequest();
  • 初始化一个请求 xhr.open('POST',url)
  • 设置一个请求头 xhr.setRequestHeader(),必须在open之后,send之前
  • 发送数据 xhr.send(data)
  • 当readyState属性发生变化时调用 xhr.onreadystatechange

参考文档

https://developer.mozilla.org/zh-CN/docs/Web/API

一个例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <input type="file" name="filename" id="fileInput" multiple>

    <div id="box"></div>

    <script>

    var fileInput = document.getElementById('fileInput')

    // 上传监听
    fileInput.onchange = function(e){
        let files = e.target.files;
        for(let i=0;i<files.length;i++){
            fileReader(files[i])
        }
    }

    //将上传file处理为reader和图片
    function fileReader(file){
        let reader = new FileReader(),img = document.createElement('img');

        reader.onload = function(){
            img.src = reader.result;            
        }

        img.onload = function(){
            imageHandler(img,{
                filename:file.name
            })

        }

        reader.readAsDataURL(file)
    }


    //图片的处理(压缩、裁切、下载、上传)
    function imageHandler(img,options){
        var canvas = document.createElement('canvas');
        canvas.width = img.width < 300 ? img.width : 300;

        let ratio = img.width/img.height;
        canvas.height = canvas.width/ratio;    

        var context = canvas.getContext('2d')
        context.drawImage(img,0,0,canvas.width,canvas.width/ratio);

        

        let base64 = canvas.toDataURL('image/jpeg',0.9)
        let image = document.createElement('img')
        image.src = base64
        image.onload = function(){
            document.getElementById('box').appendChild(image)
        }
        
        //下载
        //download(base64,options.filename)

        // 画布导出为blob并上传
        // canvas.toBlob(function(blob){
        //     console.log(blob)
        //     var formData = new FormData();
        //     formData.append('filename',blob,options.filename)
        //     httpPost('https://beihaoyun.gophper.com/upload/file',formData)
        // })

        //base64转化为blob并上传
        // var blob = base64ToBlob(base64)
        // var formData = new FormData();
        // formData.append('filename',blob,options.filename)
        // httpPost('https://beihaoyun.gophper.com/upload/file',formData)

        // base64转化为图片并上传
        // var formData = new FormData();
        // formData.append('filename',base64ToFile(base64,options.filename))
        // httpPost("https://beihaoyun.gophper.com/upload/file",formData)
    }

    //base64转file
    function base64ToFile(base64,filename) {
        var arr = base64.split(','),mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),n=bstr.length,u8arr=new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr],filename,{type:mime})
    }

    //base64转blob
    function base64ToBlob(base64){
        var arr = base64.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
        }
        return new Blob([u8arr], { type: mime });
    }

    //ajax
    function httpPost(url,params,options) {
        console.log(params)
        var xhr = new XMLHttpRequest();
        xhr.open('POST',url)
        xhr.send(params)
    }

    //下载图片
    function download(base64,filename){
        let a = document.createElement('a');
        a.href = base64
        a.download = filename+'.jpg';
        let event = document.createEvent('MouseEvent')
        event.initMouseEvent('click',false,false,window,0,0,0,0,0,false,false,false,false,0,null)
        
        var evt = new MouseEvent("click", {
            bubbles: true,
            cancelable: true,
            view: window
        });

        a.dispatchEvent(evt)
    }

    </script>
</body>
</html>

转载于:https://my.oschina.net/tongjh/blog/2875360

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值