用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)...

直接上代码,其中上传功能需要自己配置允许跨域的文件服务器地址~

或者将html文件贴到您的站点下同源上传也OK。

支持:

不同尺寸图片获取、

原图缩小放大、

原图移动、

选择框大小改变、

下载选中的区域、

上传选中的区域、

几种简单的滤镜(自己添加滤镜函数即可添加滤镜效果)

 

移动端适配要点

① 替换事件名称

if(/^.*(Android|iPad|iPhone){1}.*$/.test(navigator.userAgent)){
eventName={down:"touchstart",move:"touchmove",up:"touchend",click:"tap"};
}

② 移动端touch事件e没有clientX属性,需要做如下处理

//处理事件,支持移动端
//e.originalEvent.targetTouches[0].pageX
function dealE(e){
e.clientX= e.clientX || e.originalEvent.targetTouches[0].clientX;
e.clientY= e.clientY || e.originalEvent.targetTouches[0].clientY;
}

③ 移动端浏览器展示网页在手指拖动的过程中是会左右晃悠的,体验十分不好。

给所有事件都加上

e.preventDefault();

④ 移动端浏览器对File上传支持不好,微信甚至干脆屏蔽了File上传请求

我的做法是:

获取图片文件的base64字符串:

 var imgData = $("#res1")[0].toDataURL("png");
        imgData = imgData.replace(/^data:image\/(png|jpg);base64,/, "");

 

然后自己在后端实现一个文件上传代理,接收base64字符串,拼接body:

用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)...
 proxyRequest.ContentType = "multipart/form-data; boundary=----WebKitFormBoundaryqwqoxnDz0J0XB2Ti";
        StreamReader reader = new StreamReader(_context.Request.InputStream);
        string base64=reader.ReadToEnd();
        string divider = "----WebKitFormBoundaryqwqoxnDz0J0XB2Ti";
        string content = "";
        content += "--"+divider;
        content += "\r\n";
        content += "Content-Disposition: form-data; name=\"userlogo\"; filename=\"userlogo.png\"";
        content += "\r\n";
        content += "Content-Type: image/png";
        content += "\r\n\r\n";
        byte[] bytes1 = Encoding.UTF8.GetBytes(content);
        byte[] bytes2 = Convert.FromBase64String(base64);
        byte[] bytes3 = Encoding.UTF8.GetBytes("\r\n" + "--" + divider + "--\r\n");
        byte[] bytes = new byte[bytes1.Length+bytes2.Length+bytes3.Length];
        bytes1.CopyTo(bytes,0);
        bytes2.CopyTo(bytes, bytes1.Length);
        bytes3.CopyTo(bytes, bytes1.Length + bytes2.Length);
        proxyRequest.ContentLength = bytes.Length;
用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)...

这样对于移动端浏览器来说这就是一个普通的请求。

至此,移动端完美支持!

 

用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)...

用Canvas+Javascript FileAPI 实现一个跨平台的图片剪切、滤镜处理、上传下载工具(转)...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>get image</title>
<style>
    canvas{
        border:solid thin #ccc;
        cursor:pointer;
    }
    #canvasContainer{
        position:relative;
    }
    #picker{
        position:absolute;
        border:solid thin #ccc;
        cursor: move;
        overflow:hidden;
        z-index:2;
    }
    #resize{
         width: 0;
         height: 0;
         border-bottom: 15px solid rgba(200,200,200,0.8);
         border-left: 15px solid transparent;
         right: 0;
         bottom: 0;
         position: absolute;
         cursor: se-resize;
         z-index:3;
    }
</style>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<script>
    $(function(){
        var canvas=document.getElementById("container"),
            context=canvas.getContext("2d"),
            //文件服务器地址
            fileServer=null,
            //适配环境,随时修改事件名称
            eventName={down:"mousedown",move:"mousemove",up:"mouseup",click:"click"};
        //////////canvas尺寸配置
        var canvasConfig={
                //容器canvas尺寸
                width:500,
                height:300,
                //原图放大/缩小
                zoom:1,
                //图片对象
                img:null,
                //图片完整显示在canvas容器内的尺寸
                size:null,
                //图片绘制偏移,为了原图不移出框外,这个只能是负值or 0
                offset:{x:0,y:0},
                //当前应用的滤镜
                filter:null
        }
        canvas.width=canvasConfig.width;
        canvas.height=canvasConfig.height;
        ///////////设置选择工具配置
        var config={
            //图片选择框当前大小、最大大小、最小大小
            pickerSize:100,
            minSize:50,
            maxSize:200,
            x:canvas.width/2-100/2,
            y:canvas.height/2-100/2
        }
        /////////////结果canvas配置
        var resCanvas=[$("#res1")[0].getContext("2d"),$(