前言

图片裁剪上传,不仅是一个很贴合用户体验的功能,还能够统一特定图片尺寸,优化网站排版,一箭双雕。

需求就是那么简单,在浏览器里裁剪图片并上传到服务器。

我第一个想到的方法就是,将图片和裁剪参数(x,y,scale,rotate)一并上传给服务器,服务器来做图片处理,so easy。
但是,这并不符合潮流发展的方向:能在前端做的处理,就放前端做吧。
与潮流妥协的结果就是,前端越来越复杂。

一开始我并不认为浏览器能够读取并生成图片。想想看啊,要做"点击复制"的这样简单的功能,都需要借助 Flash 的浏览器,权限哪有那么大。

参阅各类网站,只要把图片放在本地处理的,基本上都借用了Flash。随便抄一个吧,没有API,就算能修改图片,上传路径都不知道怎么改。更关键的是,我对Flash一窍不通。

好在我们的网站已经完全抛弃了IE9以下的浏览器,只兼容现代HTML5浏览器。(连Opera和微软都开始走Webkit内核的路线了,潮流就是跟着Chrome走)只能寄希望与HTML5,于是钻研了一番,发现如下流程可行。

st=>start: 原图片 File 对象
e=>end: 上传裁剪后的Blob对象
op=>operation: 初始化Cropper 图片Base64预览
op1=>operation: 根据Cropper裁剪参数绘制Canvas(Base64)
op2=>operation: Base64转Blob对象
st->op->op1->op2->e

以下将对每个环节详解。

获取原图片 File 对象

每个图片文件处理的开始,都是由onchange事件开始

<script>
function handler(e){
var originPhoto = e.target.files[0]; // IE10+ 单文件上传取第一个
window.originFileType = originPhoto.type; //暂存图片类型
window.originFileName = originPhoto.name; //暂存图片名称
...
}
</script> <input type="file" name="demo" onchange='handler(event)' accept="image/*" >
<img id="preview">
<button onclick="cropAndUpload()">确定并上传</button>

初始化Cropper

在这里介绍一个非常好用的库 cropper.js
https://github.com/fengyuanchen/cropper
生成遮罩、获取裁剪参数、输出canvas ... 而且绝对轻量级,压缩后的css和js代码只有30KB。他是基于JQuery的,引入JQuery可能还要再大点。不过现在哪个网站没有在用JQuery呢?
兼容IE9+,移动端体验良好,能够响应触摸缩放,拖动。以下是安卓4.4 原生浏览器中的预览图

function handler(event){
...
var URL = window.URL || window.webkitURL , originPhotoURL;
originPhotoURL = URL.createObjectURL(originPhoto); //Base64
$('#preview').cropper({
aspectRatio: 1 / 1, // 固定裁剪比例1:1,裁剪后的图片为正方形
}).cropper('replace', originPhotoURL); // 动态设置图片预览
}

绘制Canvas

cropper.js 提供了生成Canvas的方法getCroppedCanvas,可以指定生成画布的大小。
或者根据getData获取裁剪信息(包括旋转和缩放)用ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)进行手动绘制。后者自由性高一点,但是既然有现成的方法,那么就直接用好了。


function cropAndUpload(){
// 此处注意,生成的Canvas长宽比应与之前规定的裁剪比例一致
// 否则生成的图片会有失真
var size = {
width:100,
height:100
}
var croppedCanvas = $('#preview').cropper("getCroppedCanvas",size); // 生成 canvas 对象
var croppedCanvasUrl = croppedCanvas.toDataURL(originFileType); // Base64
...
}

应当注意的是widthheight的值并不推荐设置成固定值。裁剪框的大小可能是会超过100100(比如500500)的,而实际生成的图片却是100100,这样的后果就是直接将一个500500的高清图片,压缩成了100100的失真图片。同样的,裁剪框小于100100,生成的图片就会模糊。


Base64 转Blob对象

字符串转为二进制?(前端本来是个做页面的,现在也开始操作文件了。自从有了HTML5,就可以把浏览器当作一个操作系统了)官方并没有出DataURLtoBlob的方法,所以只能自己写一个,转化也挺简单:拆解文件类型,将字符数据转成16进制数据存数组,并用数据初始化一个Blob对象。

function dataURLtoBlob(dataurl) {
var arr = dataurl.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});
} function cropAndUpload(){
...
var croppedBlob = dataURLtoBlob(croppedCanvasUrl);
croppedBlob.name = originFileName; // Blob对象没有name
// Upload(croppedBlob);
}

现在就可以像处理FileObject一样处理 这个blob对象了。

其实在最新的HTML5标准中是支持HTMLCanvasElement.toBlob(callback, mimeType, quality)

croppedCanvas.toBlob(function(croppedBlob){
// Upload(croppedBlob);
},originFileType)

绕了一个弯,不过还是学到了东西。

原文作者来自 MaxLeap 团队_UX成员:John王
原文链接:https://blog.maxleap.cn/archives/705

无需Flash实现图片裁剪——HTML5中级进阶的更多相关文章

  1. 无需Flash录视频——HTML5中级进阶

    前言 HTML5的权限越来越大了,浏览器可以直接调用摄像头.麦克风了,好激动啊.我们要用纯洁的HTML代码造出自己的天地. 视频采集 本篇介绍的栗子 都是在chrome 47 版本以上的,低版本的可能 ...

  2. HTML5本地图片裁剪并上传

    最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小).这个功能的需求是:头像最初剪切为一个正方形.如果选择的图片小于规定 ...

  3. Cropper – 简单的 jQuery 图片裁剪插件

    Cropper 是一个简单的 jQuery 图像裁剪插件.它支持选项,方法,事件,触摸(移动),缩放,旋转.输出的裁剪数据基于原始图像大小,这样你就可以用它们来直接裁剪图像. 如果你尝试裁剪跨域图像, ...

  4. Croppic – 免费开源的 jQuery 图片裁剪插件

    Croppic 这款开源的 jQuery 图片裁剪插件能够满足网站开发人员各种不同的使用需要.只需要简单的上传图片,就可以实现你想要的图像缩放和裁剪功能.因为使用了 HTML5 FormData  对 ...

  5. Android大图片裁剪终极解决方案(上:原理分析)

    转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-)  http://my.oschina.net/ryanhoo/blog/86842 约几个月前,我正 ...

  6. uCrop图片裁剪

    uCrop使用 github地址 https://github.com/Yalantis/uCrop然后clone或下载到本地,运行之. 效果预览 app/build.gradle compile ' ...

  7. 让Flash内心崩溃的HTML5历史

    对于HTML5,在今天这个互联网时代,大部分人应该至少都听说过这个名字,或许很多人对HTML5的了解都起于一句话:FLASH杀手. HTML5其实早已不是什么新鲜的事物了,其最初的雏形早在2004年就 ...

  8. iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码

    iOS精选源码 扩展内容的cell - folding-cell 一个近乎完整的可识别中国身份证信息的Demo 可自动快速... JPImageresizerView 仿微信的图片裁剪 带年月和至今以 ...

  9. iOS常见用户头像的圆形图片裁剪常见的几种方法

    在开发中,基本上APP的用户头像的处理都需要把用户所上传的方形图片,处理为圆形图片.在这里就总结三种常见的处理圆形图片的方法. 1.使用位图上下文 2.使用UIView的layer进行处理 3.使用r ...

随机推荐

  1. Activity的创建及生命周期

  2. 哈工大 计算机系统 实验七 TinyShell

    所有实验文件可见github 计算机系统实验整理 实验报告 实 验(七) 题 目 TinyShell 微壳 计算机科学与技术学院 目 录 第1章 实验基本信息 - 4 - 1.1 实验目的 - 4 - ...

  3. C语言中一些知识点

    1.学编程:找代码,读代码,改代码,写代码:少看书.但少看不是不看,看一本书要限制在一天内.任务是通读书中主要的概念,明白大致是干什么用的,形成一个大概的框架:然后一周内干掉书中全部代码,代码不理解再 ...

  4. 阿里云 elk 搭建

    1.logstash通过redis收集日志. logstash > redis>logstash  >es k8s日志挂载 tong sudo umount -t glusterfs ...

  5. WPF优秀组件推荐之Stylet(一)

    一.简介 Stylet是基于WPF的一款MVVM组件,虽然WPF本身是自带MVVM功能的,但实现起来不是很方便 ,通过Stylet,用户可以用很少的代码就能享受MVVM带来的舒适体验. 目前Style ...

  6. 通过媒体查询来实现 WPF 响应式设计

    WPF 客户端经常需要运行在各种不同大小屏幕下,为了显示友好,所以开发的时候都需要考虑响应式设计. 布局往往通过指定比例,而不直接指定准确的大小来实现响应式布局(如 Width="3*&qu ...

  7. Linux环境下安装Maven

    最近在搞虚拟机,记录下虚拟机内Maven环境的搭建流程 一.选择合适的版本(由于Maven运行需要依赖于JDK,所以安装之前需要保证当前虚拟机下已经安装并配置好JDK环境,安装流程参见) https: ...

  8. Mysql下载路径和安装

    下载路径 https://dev.mysql.com/downloads/mysql/ C:\Windows\system32>net start mysql 发生系统错误 2. 系统找不到指定 ...

  9. 【OpenHarmony移植案例与原理】XTS子系统之应用兼容性测试用例开发

    摘要:本文主要介绍ACTS应用兼容性测试用例开发编译. 本文分享自华为云社区<移植案例与原理 - XTS子系统之应用兼容性测试用例开发>,作者: zhushy . XTS(X Test S ...

  10. Key-Value存储系统简介

    Redis是一个Key-Value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合)和zset(有序集合).这些数据类 ...