小记-用canvas完成图像液化(向前变形)过程
前几天由于团队需要,折腾了一下图像液化的处理过程。
现在来整理一下思路,做个记录。
用到公式如下,网上拿来的
话不多说,上代码
本来想尽量写出点逼格。。。后来发现怎么写也还是几个function搞定,就那样了。
(function(global) {
// 计算两点距离平方
function distanceSqr( x1, y1, x2, y2 ) { return sqr(x1-x2) + sqr(y1-y2); }
// 计算平方
function sqr(x) { return x*x; }
// 遍历一个指定圆内的所有点
// 通过callback传入回调方法,回调传出每一个点的相关信息
function eachCircleDot( imageData, ox, oy, r, callback ) {
var imgWidth = imageData.width,
imgHeight = imageData.height,
data = imageData.data,
left = ox-r,
right = ox+r,
top = oy-r,
bottom = oy+r,
dotRedOffset,dotGreenOffset,dotBlueOffset,alphaOffset;
for( var x = left; x < right; x++ )
for( var y = top; y < bottom; y++ )
if( distanceSqr( x, y, ox, oy ) <= sqr(r) ) {
dotRedOffset = y*imgWidth*4+x*4;
dotGreenOffset = dotRedOffset + 1;
dotBlueOffset = dotGreenOffset + 1;
alphaOffset = dotBlueOffset + 1;
callback(
// 当前点的坐标
{ x:x, y:y },
// 点的RGBA四个分量对应字节的下标
{
r: dotRedOffset,
g: dotGreenOffset,
b: dotBlueOffset,
a: alphaOffset,
},
// 传进来的ImageData的data部分
data
);
}
}
// 复制一个imageData的data到一个buff里
function copyImageDataBuff( imgData ) {
var data = imgData.data,
imgDataBuff = [];
for( var i in data )
imgDataBuff[i] = data[i];
return imgDataBuff;
}
// 从buff按照指定坐标复制像素点数据到目标imageData里
function moveDot( imgData, dataBuff, x, y, srcX, srcY ) {
var imgWidth = imgData.width,
imgHeight = imgData.height,
data = imgData.data;
x = Math.floor(x);
y = Math.floor(y);
srcX = Math.floor(srcX);
srcY = Math.floor(srcY);
var targetStartOffset = y*imgHeight*4 + x*4,
srcStartOffset = srcY*imgHeight*4 + srcX*4;
for( var i = 0; i < 4; i++ )
data[ targetStartOffset + i ] = dataBuff[ srcStartOffset + i ];
}
// 执行液化过程
// imgData 通过canvas的getImageData方法得到的数据对象
// cx,cy 圆心坐标
// mx,my 移动目标坐标
// r 作用半径
// strength 力度百分比(1-100)
function liquify( imgData, cx, cy, mx, my, r, strenth ) {
var imgDataBuff = copyImageDataBuff(imgData);
eachCircleDot( imgData, cx, cy, r, function( posi ) {
var tx = posi.x,
ty = posi.y;
var u = transFormula( cx, cy, mx, my, tx, ty, r, strenth );
moveDot( imgData, imgDataBuff, tx, ty, u.x, u.y );
function transFormula( cx, cy, mx, my, tx, ty, r, strenth ) {
strenth = strenth || 100;
var relativity = sqr(r) - distanceSqr( tx, ty, cx, cy );
var distanceMovedSqr = distanceSqr( mx, my, cx, cy );
var rate = sqr( relativity / ( relativity + distanceMovedSqr*(100/strenth) ) );
var ux = tx - rate * (mx-cx),
uy = ty - rate * (my-cy);
return { x:ux, y:uy };
}
});
}
// 挂到全局对象
global.LiquifyFilter = {
liquify: liquify
};
})(window);
使用它
先用canvas的
getImageData();
方法获取到要处理图片的imageData
全局作用域下调用
LiquifyFilter.liquify( imageData, 圆心X, 圆心Y, 目标点X, 目标点Y, 作用半径, [力度百分比] );
完成转换。
然后再用canvas的
puImageData();
把转换后的imageData输出到canvas中
效果图如下
小记-用canvas完成图像液化(向前变形)过程的更多相关文章
- html5 Canvas处理图像 实例讲解
最近在学习canvas,canvas有很强大的图像处理功能,下面写一个我的学习总结: canvas常用功能: 1. 绘制矩形.圆形.曲线.组合图形 2. 绘制文本 3.绘制渐变.变形的图形 4. 图片 ...
- [转载] DSP6000图像位移与变形典型算法
原文地址:转载:DSP6000图像位移与变形典型算法作者:Jane 李现路:DSP6000图像位移与变形典型算法 一.图像的平移算法 图像平移的数学表达式原理: 初始坐标为(x0,y0)的点经过平移( ...
- 用纯Python实现循环神经网络RNN向前传播过程(吴恩达DeepLearning.ai作业)
Google TensorFlow程序员点赞的文章! 前言 目录: - 向量表示以及它的维度 - rnn cell - rnn 向前传播 重点关注: - 如何把数据向量化的,它们的维度是怎么来的 ...
- canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)
[下篇] -- 建议学习时间4小时 课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...
- canvas 绘制图像
结果: 代码: <!DOCTYPE html> <html> <head lang="en"> <meta charset="U ...
- canvas绘制图像轮廓效果
在2d图形可视化开发中,经常要绘制对象的选中效果. 一般来说,表达对象选中可以使用边框,轮廓或者发光的效果. 发光的效果,可以使用canvas的阴影功能,比较容易实现,此处不在赘述. 绘制边框 绘制 ...
- html5新特性canvas绘制图像
在前端页面开发过程中偶尔会有需要对数据进行相应的数学模型展示,或者地理位置的动态展示,可能就会想到用canvas,网上有很多已经集成好的,比如说类似echarts,确实功能非常强大,而且用到了canv ...
- H5中标签Canvas实现图像动画
一:主题部分 1.介绍 canvas可以实现画图功能,所以只要通过js的控制,就可以实现简单的动画效果. 这里主要是两个程序,一个小球来回上下弹跳,一个是吹气球. 2.弹跳程序 <!DOCTYP ...
- 【canvas】高级功能一 变形
[canvas]Demo1 scale缩放 <!DOCTYPE html> <html lang="en"> <head> <meta c ...
随机推荐
- 假如让你来设计SSL/TLS协议,你要怎么设计呢?
摘要:本文将从设计者的视角介绍如何一步步设计出一个简易版的 SSL/TLS 的过程,在文章的最后,再简单介绍 TLS 1.2 版本的工作机制,以此帮助大家对 SSL/TLS 协议的基本原理有一个更深入 ...
- SpringCloudConfig配置使用
目录 SpringCloudConfig 是什么 作用 1.创建Git仓库 2.创建配置中心服务端 创建项目 导入pom 开启@EnableConfigServer YML 测试 全部资源请求方式 3 ...
- Mysql基础语法-建库-建表(增、删、改、查、表关联及子查询)
前言:MySQL是一个数据库管理系统,也是一个关系数据库.它是由Oracle支持的开源软件,MySQL可以在各种平台上运行UNIX,Linux,Windows等.可以将其安装在服务器甚至桌面系统上. ...
- 8、msyql性能分析工具
性能分析工具 1服务器优化的步骤 2查询系统参数 在MySQL中,可以使用 SHOW STATUS 语句查询一些MySQL数据库服务器的性能参数.执行频率 . SHOW STATUS语句语法如下: S ...
- 打靶笔记-02-vulhub-Hackademic.RTB1
打靶笔记-02-vulhub-Hackademic.RTB1 一.靶机信息 Name: Hackademic: RTB1(中等难度) Date release: 6 Sep 2011 Author: ...
- LGP3281口胡
当你看到一个东西的时候,GF 有可能比 DP 更方便.处理贡献也有可能比 DP 更方便. 这个题意明显是让我们计算 \(S(r)-S(l-1)\) 之类的东西( 所以直接考虑前缀的答案就好了( 考虑将 ...
- Excel 使用 公式
1. 查询单元数据在另一列中是否存在 =VLOOKUP(E2,F:F,1,FALSE) 2.判断一列数据是否重复 =IF(COUNTIF(A:A,A2)>1,"重复",&qu ...
- Ansible的原理与配置
镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 Ansible原理 Ansible 是一款开源自动化平台.它是一种简单的自动化语言,能够在Ansible Playbook 中完美地描述 IT 应 ...
- 线程池提交任务时submit()和execute()的区别
因为之前一直是用的execute方法,最近有个情况需要用到submit方法,所以研究了下. 他们的区别: 1.execut()可以添加一个Runable任务,submit()不仅可以添加Runable ...
- C# WinForm 设置按纽为透明,使用背景色
今天开发登陆界面时,遇到一个窗体控制设置问题: 1.将按纽设置为透明: 2.并且使用背景图片的颜色: 3.并且需要当点击这个按纽时,仍然显示背景图片颜色: 4.去掉按纽边框显示线: 需要的效果如下: ...