canvas 操作者像素点

参考:https://blog.csdn.net/sinat_33488770/article/details/119298802

像素处理 https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas

  • 包含高度 × 宽度 × 4 bytes数据,索引值从0到(高度×宽度×4)-1

例如,要读取图片中位于第50行,第200列的像素的蓝色部份,你会写以下代码:

blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];
  • 根据行、列读取某像素点的R/G/B/A值的公式:
imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 0/1/2/3];
  • 你可能用会使用Uint8ClampedArray.length属性来读取像素数组的大小(以bytes为单位):
var numBytes = imageData.data.length;

颜色选择器

var img = new Image();
img.crossOrigin = 'anonymous';
img.src = './assets/rhino.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
img.onload = function() {
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
};
var hoveredColor = document.getElementById('hovered-color');
var selectedColor = document.getElementById('selected-color');


function pick(event, destination) {
  var x = event.layerX;
  var y = event.layerY;
  var pixel = ctx.getImageData(x, y, 1, 1);
  var data = pixel.data;

    const rgba = `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3] / 255})`;
    destination.style.background = rgba;
    destination.textContent = rgba;

    return rgba;
}

canvas.addEventListener('mousemove', function(event) {
    pick(event, hoveredColor);
});
canvas.addEventListener('click', function(event) {
    pick(event, selectedColor);
});

图片灰度和反相颜色

var img = new Image();
img.crossOrigin = 'anonymous';
img.src = './assets/rhino.jpg';

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

img.onload = function() {
    ctx.drawImage(img, 0, 0);
};

var original = function() {
    ctx.drawImage(img, 0, 0);
};

var invert = function() {
    ctx.drawImage(img, 0, 0);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
        data[i]     = 255 - data[i];     // red
        data[i + 1] = 255 - data[i + 1]; // green
        data[i + 2] = 255 - data[i + 2]; // blue
    }
    ctx.putImageData(imageData, 0, 0);
};

var grayscale = function() {
    ctx.drawImage(img, 0, 0);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
        var avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
        data[i]     = avg; // red
        data[i + 1] = avg; // green
        data[i + 2] = avg; // blue
    }
    ctx.putImageData(imageData, 0, 0);
};

const inputs = document.querySelectorAll('[name=color]');
for (const input of inputs) {
    input.addEventListener("change", function(evt) {
        switch (evt.target.value) {
            case "inverted":
                return invert();
            case "grayscale":
                return grayscale();
            default:
                return original();
        }
    });
}

缩放和反锯齿

<canvas id="canvas" width="300" height="227"></canvas>
<canvas id="zoom" width="300" height="227"></canvas>
<div>
<label for="smoothbtn">
  <input type="checkbox" name="smoothbtn" checked="checked" id="smoothbtn">
  Enable image smoothing
</label>
</div>

var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
img.onload = function() {
  draw(this);
};

function draw(img) {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);
  img.style.display = 'none';
  var zoomctx = document.getElementById('zoom').getContext('2d');

  var smoothbtn = document.getElementById('smoothbtn');
  var toggleSmoothing = function(event) {
    zoomctx.imageSmoothingEnabled = this.checked;
    zoomctx.mozImageSmoothingEnabled = this.checked;
    zoomctx.webkitImageSmoothingEnabled = this.checked;
    zoomctx.msImageSmoothingEnabled = this.checked;
  };
  smoothbtn.addEventListener('change', toggleSmoothing);

  var zoom = function(event) {
    var x = event.layerX;
    var y = event.layerY;
    zoomctx.drawImage(canvas,
                      Math.abs(x - 5),
                      Math.abs(y - 5),
                      10, 10,
                      0, 0,
                      200, 200);
  };

  canvas.addEventListener('mousemove', zoom);
}

加载龙的图片


let img = new Image()
img.src = './龙.jpg'
img.onload = () => {
    draw()
}
// 把图片绘制到canvas里
const draw = () => {
    const canvas = document.getElementById('canvas')
    canvas.width = img.width
    canvas.height = img.height
    const ctx = canvas.getContext('2d')
    ctx.drawImage(img, 0, 0, img.width, img.height)
    // 获取像素数据
    const imgData = ctx.getImageData(0, 0, img.width, img.height).data
    // 拼接字符
    join(imgData)
}
// 把像素数据拼接成字符
const join = (data) => {
    let gap = 10
    let str = ''
    for (let h = 0; h < img.height; h += gap) {
        str += '\n'
        for (let w = 0; w < img.width; w += gap) {
            str += ' '// 因为字符的高度普遍都比其宽度大,所以额外添加一个空字符平衡一下,否则最终的图形会感觉被拉高了
            let pos = (h * img.width + w) * 4
            let r = data[pos]
            let g = data[pos + 1]
            let b = data[pos + 2]
            // rgb转换成yuv格式,根据y(亮度)来判断显示什么字符
            let y = r * 0.299 + g * 0.578 + b * 0.114
            if (y >= 190) {
                // 浅色
                str += ' '
            } else {
                // 深色
                str += '#'
            }
        }
    }
    console.log(str)
}

网路图片生成

var http = require("http");
//文件处理
var fs = require("fs");
// req 路由监听空 res 上下文函数
var server = http.createServer((req, res) => {
  // 公共请求头
  res.writeHead(200, {
    // "Content-Type": "text/html;chaset=UTF-8",
    "Content-Type": "image/png",
    //设置允许跨域的域名,*代表允许任意域名跨域
    "Access-Control-Allow-Origin": "*",
  });
   // 路由监控
  if (req.url == "/fang") {
    res.end("fang");
  } else if (req.url == "/yuan") {
    res.end("yuan");
  } else {
    // res.end("404");
    // res.end("<a href='/fang'>fang</a><br><a href='yuan'>yuan</a>");
    // fs.readFile(path,’binary’, function (err, file) { })的参数多了一个’binary’,以二进制流的方式读取。
    // res.write(file,’binary’); response也以二进制流的方式向浏览器输出。
    fs.readFile("./sprite.png", "binary", function (err, file) {
    if (err) {
        console.log(err);
        return;
      } else {
        res.write(file, "binary");
        res.end();
      }
    });
  }
  });
  
server.listen(3000, "127.0.0.1", (res) => {
  console.log("http://127.0.0.1:3000/");
});
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

web修理工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值