小记-用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 ...
随机推荐
- k8s-静态PV和动态PV
1.pv 简单介绍 PersistenVolume(PV):对存储资源创建和使用的抽象,使得存储作为集群中的资源管理 PV分为静态和动态,动态能够自动创建PV • PersistentVolumeCl ...
- MySQL-常用的几种修改密码方法
在MySQL中一般常规的给用户修改密码可以用到以下几种方法: 1.使用 mysqladmin命令修改密码 1 mysqladmin -u username -p password "newP ...
- @PostConstruct使用注意点
前景提要:在一个项目中,由于数据库中敏感词删除掉了,但是在网页进行匹配时仍然能够匹配上已删除的词. 查看项目源码发现使用了@PostConstruct注解: 此注解的作用是:@PostConstruc ...
- 『德不孤』Pytest框架 — 11、Pytest中Fixture装饰器(一)
目录 1.Fixture装饰器的用途 2.Fixture参数说明 3.Fixture装饰器简单应用 4.yield执行后置函数 1.Fixture装饰器的用途 做测试前后的初始化设置,如测试数据准备, ...
- linux作业--第十一周
1. 导入hellodb.sql生成数据库 (1) 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄 (2) 以ClassID为分组依据,显示每组的平均年龄 (3) 显示第2题中 ...
- golang 中 channel 的详细使用、使用注意事项及死锁分析
目录 1.什么是 channel,介绍管道 2.channel 的基本使用 3.channel 的使用场景 4.使用 channel的注意事项及死锁分析 什么是 channel 管道 它是一个数据管道 ...
- mavan的安装与配置
1.下载mavan 下载路径:http://maven.apache.org/download.cgi 2.安装mavan 将下载好的压缩包解压到指定位置 3.配置系统环境变量 添加一个MAVAN_H ...
- 用 EXISTS 或 NOT EXISTS 用法
项目中遇到这么个情况: t1表 和 t2表 都是150w条数据,600M的样子,都不算大. 但是这样一句查询 ↓ select * from t1 where phone not in (selec ...
- 6张图为你分析Kafka Producer 消息缓存模型
摘要:发送消息的时候, 当Broker挂掉了,消息体还能写入到消息缓存中吗? 本文分享自华为云社区<图解Kafka Producer 消息缓存模型>,作者:石臻臻的杂货铺. 在阅读本文之前 ...
- JavaWeb 05_JDBC入门及连接MySQL
一.概念 *概念: Java DataBase Connectivity Java数据库连接, Java语言操作数据库* JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数 ...