腾讯 AlloyCrop 1.0 发布
写在前面
AlloyCrop 这个项目是8个月前发布的,作为AlloyFinger 的典型案例,发布之后被BAT等其他公司广泛使用。但是发布之后,有两个问题一直没有抽出时间去解决:
- 裁剪图像的分辨率太小,是否可配?
- pinch双指放大的时候,放大的中心不是双指中心,是否可以优化?
现在很高兴地告诉大家,AlloyCrop 已经完全搞定了上面两个问题,本文将解释新版本的变化和AlloyCrop背后的原理。当然AlloyFinger的原理这里就不再阐述,以前有分享过 超小Web手势库AlloyFinger原理
先看全新的API变化。
API
new AlloyCrop({
image_src: "img src",
circle: true, // optional parameters , the default value is false
width: 200, // crop width
height: 100, // crop height
output: 2, // output resolution --> 400*200
ok: function (base64, canvas) { },
cancel: function () { },
ok_text: "yes", // optional parameters , the default value is ok
cancel_text: "no" // optional parameters , the default value is cancel
});
| 参数 | 是否必填 | 意义 |
|---|---|---|
| image_src | 必须 | 需要裁剪图片的src地址 |
| circle | 不必须,默认是false | 代表选取的是否是圆形还是矩形,默认是矩形,注意:圆形选取裁剪出来的也是正方形图片 |
| width | 必须 | 选区的宽 |
| height | 必须 | 选区的高 |
| output | 必须 | 输出的倍率。比如如果output为2,选区的宽300,选区的高100,输出的图像的分辨率为 (2×300,2×100) |
| ok | 必须 | 点击ok按钮的回调 |
| cancel | 必须 | 点击cancel按钮的回调 |
| ok_text | 不必须,默认是ok | ok按钮的文本 |
| cancel_text | 不必须,默认是cancel | cancel按钮的文本 |
与之前版本最主要的变化就是新增了 output 支持自定义倍率分辨率的图像输出。
output原理
crop: function () {
this.calculateRect();
this.ctx.drawImage(this.img, this.crop_rect[0], this.crop_rect[1], this.crop_rect[2], this.crop_rect[3], 0, 0, this.canvas.width, this.canvas.height);
},
其中 this.calculateRect() 是计算选取和图片重叠在一起的矩形区域,drawImage 是把裁剪的区域绘制到 canvas 上。注意 canvas 的宽高是多少?且看:
this.canvas.width = option.width * this.output;
this.canvas.height = option.height * this.output;
所以就达到了自定义倍率分辨率的目的。当然这里图片的失真又或者超分辨,都取决于 drawImage 插值过程。关于插值,以前特意对比过,使用三次卷积插值完爆了其他几个,但是三次卷积插值速度也是最慢,所以浏览器内核要权衡效率和插值结果去实现 drawImage。

calculateRect计算裁剪区域
因为我们需要把图片的某个区域绘制到整个canvas上。所以drawImage的后四个参数为(0, 0, this.canvas.width, this.canvas.height),然后我们需要去计算图片裁剪的区域。

大概就分上面两种情况,一种是完全包含,一种部分相交。


因为图片会被放大或者缩小(scale),所以情况会变得稍微复杂一点点。求出相交的矩形区域后,要对图片scale进行校正,校正回到1的比例,才能用于drawImage。具体代码参见 https://github.com/AlloyTeam/AlloyCrop/blob/master/alloy-crop.js#L227-L255
pinch 缩放优化
使用AlloyCrop是可以放大或者缩小再进行裁剪,怎么基于 pinch 的两个手指的中间进行放大呢?所以的秘密都在这个multipointStart里。
- multipointStart是AlloyFinger抛出的多手指开始碰到屏幕的回调函数,通过evt.touches拿到前两个手指的坐标去计算中心坐标
- 重置 originX 和 originY 到两手指的中心
- 再重置 translateX 和 translateY 去抹平 originX和originY变更带来的位移
new AlloyFinger(this.croppingBox, {
multipointStart: function (evt) {
//reset origin x and y
var centerX = (evt.touches[0].pageX + evt.touches[1].pageX) / 2;
var centerY = (evt.touches[0].pageY + evt.touches[1].pageY) / 2;
var cr = self.img.getBoundingClientRect();
var img_centerX = cr.left + cr.width / 2;
var img_centerY = cr.top + cr.height / 2;
var offX = centerX - img_centerX;
var offY = centerY - img_centerY;
var preOriginX = self.img.originX
var preOriginY = self.img.originY
self.img.originX = offX / self.img.scaleX;
self.img.originY = offY / self.img.scaleY;
//reset translateX and translateY
self.img.translateX += offX - preOriginX * self.img.scaleX;
self.img.translateY += offY - preOriginY * self.img.scaleX;
self.initScale = self.img.scaleX;
},
pinch: function (evt) {
self.img.scaleX = self.img.scaleY = self.initScale * evt.zoom;
},
pressMove: function (evt) {
self.img.translateX += evt.deltaX;
self.img.translateY += evt.deltaY;
evt.preventDefault();
}
});
- 注意,translateX, translateY, translateZ, scaleX, scaleY, scaleZ, rotateX, rotateY, rotateZ, skewX, skewY, originX, originY, originZ 都是 css3transform 类库 注入到DOM元素上的属性。
Preview

Demo

Dependencies
License
This content is released under the MIT License.
腾讯 AlloyCrop 1.0 发布的更多相关文章
- 腾讯 Omi 5.0 发布 - Web 前端 MVVM 王者归来,mappingjs 强力加持
写在前面 腾讯 Omi 框架正式发布 5.0,依然专注于 View,但是对 MVVM 架构更加友好的集成,彻底分离视图与业务逻辑的架构. 你可以通过 omi-cli 快速体验 MVVM: $ npm ...
- Surging1.0发布在即,.NET开发者们,你们还在等什么?
Surging1.0发布在即,.NET开发者们,你们还在等什么? 开源,是近三十年来互联网经久不衰的话题.它不仅仅是一种技术分享的形态,更是一种开放,包容,互利共赢的互联网精神. 不到30年前,大神林 ...
- 腾讯 angel 3.0:高效处理模型
腾讯 angel 3.0:高效处理模型 紧跟华为宣布新的 AI 框架开源的消息,腾讯又带来了全新的全栈机器学习平台 angel3.0.新版本功能特性覆盖了机器学习的各个阶段,包括:特征工程.模型训练. ...
- Visual Studio Code 1.0发布,支持中文在内9种语言
Visual Studio Code 1.0发布,支持中文在内的9种语言:Simplified Chinese, Traditional Chinese, French, German, Italia ...
- Apache Flume 1.7.0 发布,日志服务器
Apache Flume 1.7.0 发布了,Flume 是一个分布式.可靠和高可用的服务,用于收集.聚合以及移动大量日志数据,使用一个简单灵活的架构,就流数据模型.这是一个可靠.容错的服务. 本次更 ...
- Percona Server 5.6.33-79.0 发布
Percona Server 5.6.33-79.0 发布了,该版本基于 MySQL 5.6.33,包含了所有的 bug 修复,是Percona Server 5.6 系列中的正式版本.该版本主要是修 ...
- Rubinius 2.0 发布,Ruby 虚拟机
Rubinius 2.0 发布了,官方发行说明请看这里. Rubinius是一个运行Ruby程序的虚拟机,其带有Ruby的核心库. Rubinius的设计决定了其调试功能的强大,使得在运行时常规的Ru ...
- Restful.Data v2.0发布,谢谢你们的支持和鼓励
v1.0发布后,承蒙各位博友们的热心关注,也给我不少意见和建议,在此我真诚的感谢 @冰麟轻武 等朋友,你们的支持和鼓励,是这个开源项目最大的推动力. v2.0在除了细枝末节外,在功能上主要做了一下更新 ...
- 网页动物园2.0发布,经过几个月的努力,采用JAVA编写!
网页动物园2.0发布,经过几个月的努力,采用JAVA编写! 网页动物园2.0 正式发布!游戏发布 游戏名称: 网页动物园插件 游戏来源: 原创插件 适用版本: Discuz! X1.5 - X3.5 ...
随机推荐
- Spring事务管理—aop:pointcut expression解析
先来看看这个spring的配置文件的配置: <!-- 事务管理器 --> <bean id="transactionManager" class="o ...
- Java NIO学习笔记 NIO选择器
Java NIO选择器 A Selector是一个Java NIO组件,可以检查一个或多个NIO通道,并确定哪些通道已准备就绪,例如读取或写入.这样一个线程可以管理多个通道,从而管理多个网络连接. 为 ...
- css3动画小案例
今天与大家来分享一下我做的css3动画案例. 在展示我的案例之前先给大家说说实现这个案例所需要的一些属性. transform 属性允许我们对元素进行旋转.缩放.移动或倾斜. 通过 CSS3 2D转换 ...
- VisualSVN 5.1.7破译License Key
前面手敲一些简要的软件说明:visualSVN server大家都不陌生,服务器上的版本控制系统,一般配套Tortoisesvn(小乌龟)使用.本次介绍的这个visualsvn属于VisualStud ...
- python flask(多对多表查询)
我们在flask的学习中,会难免遇到多对多表的查询,今天我也遇到了这个问题.那么我想了好久.也没有想到一个解决的办法,试了几种方法,可能是思路的限制我放弃了,后来,我就在网上百度,可是发现百度出来的结 ...
- Quartz使用-入门使用
注:这里使用的是Quartz1.6.5版本(包:quartz-1.6.5.jar) //测试main函数 //QuartzTest.java package quartzPackage; import ...
- celery的使用
1.celery的任务调度 # -*- coding: utf-8 -*- import threading from bs4 import BeautifulSoup from tornado im ...
- 6.function自定义插件的方法和使用
Smarty插件本质上是一个function函数 有三种类型的插件: function modifier block functions 定义的方法有三种: 1.使用registerPlugin的方法 ...
- c# ActiveMQ 类
using System;using System.Collections.Generic;using System.Text; using Apache.NMS;using Apache.NMS.A ...
- Educational Codeforces Round 20.C
C. Maximal GCD time limit per test 1 second memory limit per test 256 megabytes input standard input ...