摘要:此脚本的功能是将格式的图片中的白色背景转成透明,然后再保存成格式的图片如果图片本身有不想被转换的白色区域,使用其他方法吧。所以说如果我们想实现白色背景的图片转成透明的图片,只需要将白色背景对应的像素点得值变成就好了。
作者 @zwhu
源码 @raw
原文章 @github
老板让我这个不会P图的伪前端把公司的Logo放到公司网站上,结果给了我一张 JPEG 格式的图片,作为一个有追求的码农,怎么能现学 ps,于是利用一点HTML5+NODE的知识写了个转换的脚本。
此脚本的功能是将 JPEG 格式的图片中的白色背景转成透明,然后再保存成PNG格式的图片;如果图片本身有不想被转换的白色区域,使用其他方法吧。
实现原理原理很简单,只有两点:
RGBARGBA的解释 我们知道图片由很多个像素点组成的,每个像素点都有颜色,而颜色是由三基色RGB构成。而A是Alpha通道,用作不透明度参数,0%为完全透明,100%是完全不透明。所以说如果我们想实现白色背景的JPEG 图片转成透明的 PNG 图片,只需要将白色背景对应的像素点得Alpha值变成0就好了。
canvasHTML5新增加了canvas,可以用来绘制图形,也可以对图片的像素进行操作。通过 getImageData() 方法可以返回原始的像素信息 ImageData 对象。ImageData 对象中的像素是可写的(由 RGBA 组成),因此我们可以修改像素的Alpha通道值,然后再通过 putImageData() 方法将这些像素复制到画布中。
部分代码有了上面的知识,我们可以很轻松的通过查 canvas 的 API 来写出转换的代码(ES6),代码在下面,代码不难,也写了很详细的注释,虽然我是用 node-canvas 实现的,但是改成浏览器版本的话,也不需要几行代码,原理是想通的:
import Canvas from "canvas"
import fs from "fs"
const Image = Canvas.Image
// 初始化 img 和 start time
// 获取命令行输入的源图片和保存的图片地址
let img = new Image
, start = new Date()
, rawPath = process.argv[2]
, savePath = process.argv[3]
// 在命令行中没有输入图片地址,抛错
if(!rawPath)
throw new Error("input raw image path")
if(!savePath)
throw new Error("input save image path")
img.onerror = function(err){
throw err
}
// 图片加载完成
img.onload = function(){
// 获取图片的width和height
let width = img.width
, height = img.height
, canvas = new Canvas(width, height)
, ctx = canvas.getContext("2d")
// 将源图片复制到画布上
// canvas 所有的操作都是在 context 上,所以要先将图片放到画布上才能操作
ctx.drawImage(img, 0, 0, width, height)
let imageData = ctx.getImageData(0, 0, width, height)
// 获取画布的像素信息
// 是一个一维数组,包含以 RGBA 顺序的数据,数据使用 0 至 255(包含)的整数表示
// 如:图片由两个像素构成,一个像素是白色,一个像素是黑色,那么 data 为
// [255,255,255,255,0,0,0,255]
// 这个一维数组可以看成是两个像素中RBGA通道的数组的集合即:
// [R,G,B,A].concat([R,G,B,A])
, data = imageData.data
// 对像素集合中的单个像素进行循环,每个像素是由4个通道组成,所以 i=i+4
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 < 256 && v > 245)) data[i+3] = 0
}
// 将修改后的代码复制回画布中
ctx.putImageData(imageData, 0, 0)
// 将修改后的图片保存
let out = fs.createWriteStream(`${__dirname}/${savePath}`)
, stream = canvas.pngStream()
stream.on("data", function (chunk) {
out.write(chunk)
})
stream.on("end", function () {
console.log(`保存到 ${__dirname}/${savePath}`)
console.log(`耗时: ${new Date()-start}ms`)
})
}
img.src = `${__dirname}/${rawpath}`
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/85967.html
摘要:本文会介绍位图处理,矢量图和图像处理,重点是,并且最后会附上一个小应用。以上列举部分,更多备胎在此矢量图处理讲完位图再说矢量图。矢量图在绘制图标商业动画元素上应用非常广范。 计算机图像处理是一门很成熟的技术,任何一门可操作系统接口的语言都能很轻易的实现各种处理操作。但是前端限于浏览器环境和接口限制,处理起来会有诸多不便,这里所说的前端图像处理,是真的指不借助任何后端服务纯前端实现的图像...
阅读 3265·2021-11-23 09:51
阅读 1872·2021-10-15 09:39
阅读 1250·2021-08-03 14:03
阅读 3117·2019-08-30 15:53
阅读 3666·2019-08-30 15:52
阅读 2707·2019-08-29 16:17
阅读 3121·2019-08-29 16:12
阅读 1808·2019-08-29 15:26