js代码片段纪要

node

1. base64数据转图片

const fs = require('fs');
const path = require('path');
const pwdPath = path.resolve(__dirname); // 当前文件路径
const imgPath = pwdPath + 'trans.png'; //从app.js级开始找--在我的项目工程里是这样的

/**
 * @description base64转图片
 * @param [String] imgPath 图片保存路径
 * @param [String] imgData 图片base64数据
 */
function base64ToImg(imgPath, imgData) {
  const base64 = imgData.replace(/^data:image\/\w+;base64,/, ''); //去掉图片base64码前面部分data:image/png;base64
  const dataBuffer = Buffer.from(base64, 'base64'); //把base64码转成buffer对象,
  if (Buffer.isBuffer(dataBuffer)) {
    fs.writeFileSync(imgPath, dataBuffer, function (err) {
      //用fs写入文件
      if (err) console.log(err);
    });
  } else {
    throw '非base数据!';
  }
}
// 使用
let imgPath = pwdPath + '/asset/test.jpg'; // 图片保存路径
base64ToImg(imgPath, imgBase64);

如果照片类型要灵活的话可以把imgPath修改下就好了

2.图片转base64

const mimeType = require('mime-types'); // 获取文件类型
const path = require('path');

/**
 * @description 图片转base64
 * @param [String] file 图片路径
 * @return 图片base64数据
 */
function imgToBase64(file) {
  const filePath = path.resolve(file); // 原始文件地址
  const fileName = filePath.split('\\').slice(-1)[0].split('.'); // 提取文件名
  const fileMimeType = mimeType.lookup(filePath); // 获取文件的 memeType

  // 如果不是图片文件,则退出
  if (!fileMimeType.toString().includes('image')) {
    return;
  }

  // 读取文件数据
  let data = fs.readFileSync(filePath);
  data = Buffer.from(data).toString('base64');

  // 转换为 data:image/jpeg;base64,***** 格式的字符串
  const base64 = 'data:' + fileMimeType + ';base64,' + data;
  return base64;
}

3. 制作透明背景图片

这里用到了canvas依赖包,如果想进一步处理图片的话推荐images、jimp、sharp三个node的图片处理库,具体文档可以上npm官网去查看。

const { Image, createCanvas } = require('canvas');
const fs = require('fs');
const pwdPath = path.resolve(__dirname); // 当前文件路径
/**
 * @description 制作透明图片
 * @param [Number] width 图片宽度
 * @param [Number] height 图片高度
 * @param [Number] max 图片最大灰度值
 * @param [Number] min 图片最小灰度值
 * @param [String] inPath 输入图片路径
 * @param [String] outPath 图片保存路径
 */
function transparent(
  width = 320,
  height = 180,
  max = 256,
  min = 0,
  inPath,
  outPath = pwdPath + `/${new Date().getTime()}.jpg`
) {
  const img = new Image();
  img.onload = () => {
    const canvas = createCanvas(width, height);
    const context = canvas.getContext('2d');
    context.drawImage(img, 0, 0, width, height);
    let imageData = context.getImageData(0, 0, width, height),
      data = imageData.data;
    for (let i = 0; i < data.length; i += 4) {
      // 得到 RGBA 通道的值
      let r = data[i];
      g = data[i + 1];
      b = data[i + 2];
      // 我们从最下面那张颜色生成器中可以看到在图片的右上角区域,有一小块在
      // 肉眼的观察下基本都是白色的,所以我在这里把 RGB 值都在 245 以上的
      // 的定义为白色
      // 大家也可以自己定义的更精确,或者更宽泛一些
      if ([r, g, b].every(v => v < max && v >= min)) data[i + 3] = 0;
    }
    // 将修改后的代码复制回画布中
    context.putImageData(imageData, 0, 0);
    const path = outPath; // 输出图片路径
    const base64 = canvas.toDataURL().replace(/^data:image\/\w+;base64,/, ''); //去掉图片base64码前面部分data:image/png;base64
    const dataBuffer = Buffer.from(base64, 'base64'); //把base64码转成buffer对象,
    // console.log('datauffer是否是Buffer对象:' + Buffer.isBuffer(dataBuffer));
    fs.writeFileSync(path, dataBuffer, function (err) {
      //用fs写入文件
      if (err) {
        console.log(err);
      } else {
        console.log('写入成功!');
      }
    });
  };
  img.src = inPath;
}
// 使用
// 有时候由于node异步的关系需要加上延时函数
await delay(50); // 来自片段4
transparent(60, 180, 10, 0, path.join(pwdPath, 'inIMG.jpg'), path.join(pwdPath, 'outIMG.jpg')); 

4. delay延时功能实现

虽然有一个settimeout但是它只是延后执行,并不会在原地停留。在settimeout的基础上稍加修改就可以实现原地延时的效果

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

async function something() {
    console.log("this might take some time....");
    await delay(5000);
    console.log("done!")
}

something();

5. 纯js绘制滑块拼图验证图片

const path = require('path');
const pwdPath = path.resolve(__dirname); // 当前文件路径
const { Image } = require('canvas'); // 引入image
const w = 40, // 正方形边长
  r = 9, // 圆形直径
  PI = Math.PI;
const L = w + r * 2 + 3 // 滑块实际边长

function() {
  const  width = 320, height = 180;
  const index = Math.floor(Math.random() * 8);
  const bgCanvas = createCanvas(width, height);
  const dragCanvas = createCanvas(width, height);
  const background = bgCanvas.getContext('2d');
  const dragPic = dragCanvas.getContext('2d');

  const image = new Image();
  image.onload = () => {
    // 随机位置创建拼图形状
    const X = getRandomNumberByRange(L + 10, width - (L + 10))
    const Y = getRandomNumberByRange(10 + r * 2, height - (L + 10))
    drawPath(background, X, Y, 'fill')
    drawPath(dragPic, X, Y, 'clip')
  
    // 画入图片
    background.drawImage(image, 0, 0, width, height)
    dragPic.drawImage(image, 0, 0, width, height)
  
    // 提取滑块并放到最左边
    const y = Y - r * 2 - 1
    const ImageData = dragPic.getImageData(X - 3, y, L, L)
    dragPic.putImageData(ImageData, 0, y)
    dragPic.drawImage(image, 0, 0, 65, 180)

  };
  image.onerror = err => {
    console.error(err);
  };
  image.src = path.join(pwdPath, `/asset/${index}.jpg`);

  let imgPath = pwdPath + '/asset/test.jpg';
  base64ToImg(imgPath, bgCanvas.toDataURL());

  imgPath = pwdPath + '/asset/test1.jpg';
  base64ToImg(imgPath, dragCanvas.toDataURL());

  const sliderCanvas = createCanvas(65, 180);
  const slider = sliderCanvas.getContext('2d');
  const sliderImg = new Image()
  sliderImg.onload=() =>{
    slider.drawImage(sliderImg, 0, 0, 65, 180, 0, 0, 65, 180)
  }
  image.onerror = err => {
    console.error(err);
  };
  sliderImg.src = dragCanvas.toDataURL();

  imgPath = pwdPath + '/asset/test2.jpg';
  base64ToImg(imgPath, sliderCanvas.toDataURL());
}
// 绘制滑块及背景
function drawPath (ctx, x, y, operation) {
  ctx.beginPath()
  ctx.moveTo(x, y)
  ctx.arc(x + w / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
  ctx.lineTo(x + w, y)
  ctx.arc(x + w + r - 2, y + w / 2, r, 1.21 * PI, 2.78 * PI)
  ctx.lineTo(x + w, y + w)
  ctx.lineTo(x, y + w)
  ctx.arc(x + r - 2, y + w / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
  ctx.lineTo(x, y)
  ctx.lineWidth = 2
  ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
  ctx.stroke()
  ctx.globalCompositeOperation = 'destination-over'
  operation === 'fill'? ctx.fill() : ctx.clip()
}

// 获取随机数
function getRandomNumberByRange (start, end) {
  return Math.round(Math.random() * (end - start) + start)
}

test.jpg
在这里插入图片描述
test1.jpg
在这里插入图片描述
test2.jpg
在这里插入图片描述

后面有别的再来补充

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值