前几天由于团队需要,折腾了一下图像液化的处理过程。

现在来整理一下思路,做个记录。

用到公式如下,网上拿来的

话不多说,上代码

本来想尽量写出点逼格。。。后来发现怎么写也还是几个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);

使用它

  1. 先用canvas的

    getImageData();

    方法获取到要处理图片的imageData

  2. 全局作用域下调用

    LiquifyFilter.liquify( imageData, 圆心X, 圆心Y, 目标点X, 目标点Y, 作用半径, [力度百分比] );

    完成转换。

  3. 然后再用canvas的

    puImageData();

    把转换后的imageData输出到canvas中

效果图如下

小记-用canvas完成图像液化(向前变形)过程的更多相关文章

  1. html5 Canvas处理图像 实例讲解

    最近在学习canvas,canvas有很强大的图像处理功能,下面写一个我的学习总结: canvas常用功能: 1. 绘制矩形.圆形.曲线.组合图形 2. 绘制文本 3.绘制渐变.变形的图形 4. 图片 ...

  2. [转载] DSP6000图像位移与变形典型算法

    原文地址:转载:DSP6000图像位移与变形典型算法作者:Jane 李现路:DSP6000图像位移与变形典型算法 一.图像的平移算法 图像平移的数学表达式原理: 初始坐标为(x0,y0)的点经过平移( ...

  3. 用纯Python实现循环神经网络RNN向前传播过程(吴恩达DeepLearning.ai作业)

    Google TensorFlow程序员点赞的文章!   前言 目录: - 向量表示以及它的维度 - rnn cell - rnn 向前传播 重点关注: - 如何把数据向量化的,它们的维度是怎么来的 ...

  4. canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)

    [下篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  5. canvas 绘制图像

    结果: 代码: <!DOCTYPE html> <html> <head lang="en"> <meta charset="U ...

  6. canvas绘制图像轮廓效果

    在2d图形可视化开发中,经常要绘制对象的选中效果. 一般来说,表达对象选中可以使用边框,轮廓或者发光的效果.  发光的效果,可以使用canvas的阴影功能,比较容易实现,此处不在赘述. 绘制边框 绘制 ...

  7. html5新特性canvas绘制图像

    在前端页面开发过程中偶尔会有需要对数据进行相应的数学模型展示,或者地理位置的动态展示,可能就会想到用canvas,网上有很多已经集成好的,比如说类似echarts,确实功能非常强大,而且用到了canv ...

  8. H5中标签Canvas实现图像动画

    一:主题部分 1.介绍 canvas可以实现画图功能,所以只要通过js的控制,就可以实现简单的动画效果. 这里主要是两个程序,一个小球来回上下弹跳,一个是吹气球. 2.弹跳程序 <!DOCTYP ...

  9. 【canvas】高级功能一 变形

    [canvas]Demo1 scale缩放 <!DOCTYPE html> <html lang="en"> <head> <meta c ...

随机推荐

  1. 哈工大 信息安全实验 XSS跨站脚本攻击原理与实践

    XX大学XX学院 <网络攻击与防御> 实验报告 实验报告撰写要求 实验操作是教学过程中理论联系实际的重要环节,而实验报告的撰写又是知识系统化的吸收和升华过程,因此,实验报告应该体现完整性. ...

  2. Python:取整函数、四舍五入

    int(a) 绝对值向0方向取整,符号不变 math.ceil(a) 向正无穷取整 math.floor(a) 向负无穷取整 round(a,n=0) 四舍五入,第二个参数说明保留小数位数

  3. laravel 返回统一的json数据

    laravel 在Api接口开发中,可以使用 response()->json(["code"=>200,"msg"=>"ok&qu ...

  4. querylist 在laravel框架中的简单采集数据(专业5)

    //爬虫网站路由Route::get('/querylist/list','querylistControllers@querylist'); //控制器 <?phpnamespace App\ ...

  5. cookie、session和Storage

    概念: cookie:HTTP响应头的一部分,通过name=value的形式存储,主要用于保存登录信息.在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭. 存放数据大小为4K左右 .有个 ...

  6. java面试:多线程

    1.多线程 ​ 同步:发送一个指令需要等待返回才能发送下一条(完成一件事才能做下一件). ​ 异步:发送一个请求不需要等待返回,随时可以再发下一条(一次进行多个事件) 线程不安全根本原因是异步,对一个 ...

  7. 软件工程homework-002

    博客信息 沈阳航空航天大学计算机学院2020软件工程作业 作业要求 https://edu.cnblogs.com/campus/sau/Computer1701-1705/homework/1058 ...

  8. vue 通信:父子通信、兄弟通信、跨多层通信、vuex状态管理

    之前简单做了一次vue通信方法的培训,在此记录一下培训的内容. 关于vue通信,大家最先想到的方法应该是props.ref.$emit.$parent,还有vuex,因为这也是我在项目中最常用到的方法 ...

  9. 理解HMM算法

    长这样: 理解的前提: (1)状态:生成观测值的变量(上图中的"吃"和"睡"). (2)观测值:状态乘上输出概率对应的输出(上图中的橙色节点). (3)输出概率 ...

  10. 论文解读(VGAE)《Variational Graph Auto-Encoders》

    Paper Information Title:Variational Graph Auto-EncodersAuthors:Thomas Kipf, M. WellingSoures:2016, A ...