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 type="module"> import { ColorMapFilter } from 'https://cdn.jsdelivr.net/npm/@pixi/filter-color-map@5.1.1/+esm' 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 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>