pixi.js实现lut颜色映射滤镜实例页面
回到相关文章 »效果:
原始图片
处理图片
代码:
HTML代码:
<h4>原始图片</h4>
<p>
<img src="./example.jpg" alt="原始图">
</p>
<h4>处理图片</h4>
<canvas width="600" height="258"></canvas>
JS代码:
<script src="./pixi.js"></script>
<script src="./pixi-filters.min.js"></script>
<script type="module">
const imgUrl = './example.jpg';
const cubeUrl = './Candlelight.cube';
// canvas 元素与转换成PIXI的view
const canvas = document.querySelector('canvas');
const view = canvas.transferControlToOffscreen();
const app = new PIXI.Application({
view,
width: 600,
height: 258,
resolution: 1
});
// 加载图片
const imgContainer = new PIXI.Container();
app.stage.addChild(imgContainer);
// 图片精灵
const imgSprite = PIXI.Sprite.from(imgUrl);
imgSprite.width = 600;
imgSprite.height = 258;
imgContainer.addChild(imgSprite);
// 加载cube文件为文本格式
fetch(cubeUrl).then(res => res.text()).then(text => {
const lut = parseCubeLUT(text);
const lutImage = lut2Img(lut);
const colorMapFilter = new PIXI.filters.ColorMapFilter(lutImage);
imgContainer.filters = [colorMapFilter];
});
// 解析cube文件的方法
const parseCubeLUT = function (str) {
if (typeof str !== 'string') {
str = str.toString();
}
var title = null;
var type = null;
var size = 0;
var domain = [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]];
var data = [];
var lines = str.split('\n');
for (var i=0; i<lines.length; i++) {
var line = lines[i].trim();
if(line[0] === '#' || line === '') {
// Skip comments and empty lines
continue;
}
var parts = line.split(/\s+/);
switch(parts[0]) {
case 'TITLE':
title = line.slice(7, -1);
break;
case 'DOMAIN_MIN':
domain[0] = parts.slice(1).map(Number);
break;
case 'DOMAIN_MAX':
domain[1] = parts.slice(1).map(Number);
break;
case 'LUT_1D_SIZE':
type = '1D';
size = Number(parts[1]);
break;
case 'LUT_3D_SIZE':
type = '3D';
size = Number(parts[1]);
break;
default:
data.push(parts.map(Number));
}
}
return {
title: title,
type: type,
size: size,
domain: domain,
data: data
};
}
// cube data 转PNG图片的实现
const lut2Img = function (lutData) {
const { size, data } = lutData;
// 根据size创建canvas元素
const canvas = document.createElement('canvas');
canvas.width = size * size;
canvas.height = size;
// 绘制在Canvas上
const context = canvas.getContext('2d');
const imagedata = context.createImageData(canvas.width, canvas.height);
// 给对应坐标位置的数据设置色值为绿色
let startX = 0;
let startY = 0;
for (var x = 0; x < data.length; x++) {
// var index = 4 * x;
// 垂直计算位置
startY = Math.floor(x / size) % size;
startX = x % size + size * Math.floor(Math.floor(x / size) / size);
// index 计算
var index = 4 * (startY * size * size + startX);
imagedata.data[index] = data[x][0] * 255;
imagedata.data[index + 1] = data[x][1] * 255;
imagedata.data[index + 2] = data[x][2] * 255;
imagedata.data[index + 3] = 255;
}
// 再重绘
context.putImageData(imagedata, 0, 0);
return canvas;
};
</script>