node压缩图⽚_推荐10个常⽤的图⽚处理⼩帮⼿(下)「值得
收藏」
作者: semlinker
前⾔
本⽂给⼩伙伴们隆重介绍⽤于图⽚处理的⼗个 「“⼩帮⼿”」,他们各个⾝怀绝技,拥有模糊、压缩、裁剪、旋转、合成、⽐对等技能。相信认识他们之后,你将能够轻松应对⼤多数的图⽚处理场景。
该章节你将会学到以下知识:
如何区分图⽚的类型(可⽂件后缀名);
如何获取图⽚的尺⼨(可右键查看图⽚信息);
如何预览本地图⽚(⾮图⽚阅读器);
如何实现图⽚压缩(⾮图⽚压缩⼯具);
如何操作位图像素数据(⾮ PS 等图⽚处理软件);
如何实现图⽚隐写(⾮⾁眼可见)。
⼗个图⽚处理 「“⼩帮⼿”」 已经已经迫不及待想与你见⾯,还在犹豫什么?赶紧出发吧!
⽬录
推荐10个常⽤的图⽚处理⼩帮⼿(上)「值得收藏」
推荐10个常⽤的图⽚处理⼩帮⼿(下)「值得收藏」 本篇
2.10 Sharp
❝
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images. Uses the libvips library.
❞
Sharp 的典型应⽤场景是将常见格式的⼤图像转换为尺⼨较⼩,对⽹络友好的 JPEG,PNG 和 WebP 格式的图像。由于其内部使⽤libvips ,使得调整图像⼤⼩通常⽐使⽤ ImageMagick 和 GraphicsMagick 设置快 4-5 倍 。除了⽀持调整图像⼤⼩之外,Sharp 还⽀持旋转、提取、合成和伽马校正等功能。
Sharp ⽀持读取 JPEG,PNG,WebP,TIFF,GIF 和 SVG 图像。输出图像可以是 JPEG,PNG,WebP 和 TIFF 格式,也可以是未压缩
的原始像素数据。
「使⽤⽰例」
// 改变图像尺⼨sharp(inputBuffer) .resize(320, 240) .toFile('output.webp', (err, info) => { ... }); // 旋转输⼊图像并改变图⽚尺⼨ sharp(
「在线⽰例」
❝
❞
svg canvas该⽰例是来⾃阿宝哥 18 年写的 “Sharp ⽜⼑⼩试之⽣成专属分享图⽚” 这篇⽂章,主要是利⽤ Sharp 提供的图⽚合成功能为每个⽤户
⽣成专属的分享海报,感兴趣的⼩伙伴可以阅读⼀下原⽂哟。
const sharp = require("sharp");const TextToSVG = require("text-to-svg");const path = require("path");// 加载字体⽂件const textToSVG = TextToSVG.loadSync(pat
三、阿宝哥有话说
3.1 如何区分图⽚的类型
「计算机并不是通过图⽚的后缀名来区分不同的图⽚类型,⽽是通过 “魔数”(Magic Number)来区分。」 对于某⼀些类型的⽂件,起始
的⼏个字节内容都是固定的,根据这⼏个字节的内容就可以判断⽂件的类型。
常见图⽚类型对应的模数如下表所⽰:
⽂件类型⽂件后缀魔数JPEGjpg/jpeg0xFFD8FFPNGpng0x89504E47GIFgif0x47494638(GIF8)BMPbmp0x424D
这⾥我们以阿宝哥的头像(abao.png)为例,验证⼀下该图⽚的类型是否正确:
在⽇常开发过程中,如果遇到检测图⽚类型的场景,我们可以直接利⽤⼀些现成的第三⽅库。⽐如,你想要判断⼀张图⽚是否为 PNG 类
型,这时你可以使⽤ is-png 这个库,它同时⽀持浏览器和 Node.js,使⽤⽰例如下:
「Node.js」
// npm install read-chunkconst readChunk = require('read-chunk'); const isPng = require('is-png');const buffer = readChunk.sync('unicorn.png', 0, 8);isPng(buffer)「Browser」
(async () => { const response = await fetch('unicorn.png'); const buffer = await response.arrayBuffer(); isPng(new Uint8Array(buffer)); //=> true})();
3.2 如何获取图⽚的尺⼨
图⽚的尺⼨、位深度、⾊彩类型和压缩算法都会存储在⽂件的⼆进制数据中,我们继续以阿宝哥的头像(abao.png)为例,来了解⼀下实际的
情况:
❝
528(⼗进制) => 0x0210
560(⼗进制)=> 0x0230
❞
因此如果想要获取图⽚的尺⼨,我们就需要依据不同的图⽚格式对图⽚⼆进制数据进⾏解析。幸运的是,我们不需要⾃⼰做这件
事,image-size 这个 Node.js 库已经帮我们实现了获取主流图⽚类型⽂件尺⼨的功能:
「同步⽅式」
var sizeOf = require('image-size');var dimensions = sizeOf('images/abao.png');console.log(dimensions.width, dimensions.height);
「异步⽅式」
var sizeOf = require('image-size');sizeOf('images/abao.png', function (err, dimensions) { console.log(dimensions.width, dimensions.height);});
image-size 这个库功能还是蛮强⼤的,除了⽀持 PNG 格式之外,还⽀持 BMP、GIF、ICO、JPEG、SVG 和 WebP 等格式。
3.3 如何预览本地图⽚
利⽤ HTML FileReader API,我们也可以⽅便的实现图⽚本地预览功能,具体代码如下:
在完成本地图⽚预览之后,可以直接把图⽚对应的 Data URLs 数据提交到服务器。针对这种情形,服务端需要做⼀些相关处理,才能正常
保存上传的图⽚,这⾥以 Express 为例,具体处理代码如下:
const app = require('express')();app.post('/upload', function(req, res){ let imgData = req.body.imgData; // 获取POST请求中的base64图⽚数据 let base64Data =
3.4 如何实现图⽚压缩
在⼀些场合中,我们希望在上传本地图⽚时,先对图⽚进⾏⼀定的压缩,然后再提交到服务器,从⽽减少传输的数据量。在前端要实现图⽚
压缩,我们可以利⽤ Canvas 对象提供的 toDataURL() ⽅法,该⽅法接收 type 和 encoderOptions 两个可选参数。
其中 type 表⽰图⽚格式,默认为 image/png。⽽ encoderOptions⽤于表⽰图⽚的质量,在指定图⽚格式为 image/jpeg 或
image/webp的情况下,可以从 0 到 1 的区间内选择图⽚的质量。如果超出取值范围,将会使⽤默认值 0.92,其他参数会被忽略。
下⾯我们来看⼀下具体如何实现图⽚压缩:
function compress(base64, quality, mimeType) { let canvas = ateElement("canvas"); let img = ateElement("img"); ssO 对于返回的 Data URL 格式的图⽚数据,为了进⼀步减少传输的数据量,我们可以把它转换为 Blob 对象:
function dataUrlToBlob(base64, mimeType) { let bytes = window.atob(base64.split(",")[1]); let ab = new ArrayBuffer(bytes.length); let ia = new Uint8Array 在转换完成后,我们就可以压缩后的图⽚对应的 Blob 对象封装在 FormData 对象中,然后再通过 AJAX 提交到服务器上:
function uploadFile(url, blob) { let formData = new FormData(); let request = new XMLHttpRequest();
formData.append("image", blob); request.open("P
3.5 如何操作位图像素数据
如果想要操作图⽚像素数据,我们可以利⽤ CanvasRenderingContext2D 提供的 getImageData 来获取图⽚像素数据,其中getImageData() 返回⼀个 ImageData 对象,⽤来描述 canvas 区域隐含的像素数据,这个区域通过矩形表⽰,起始点为(sx, sy)、宽为sw、⾼为 sh。其中 getImageData⽅法的语法如下:
相应的参数说明如下:
sx:将要被提取的图像数据矩形区域的左上⾓ x 坐标。
sy:将要被提取的图像数据矩形区域的左上⾓ y 坐标。
sw:将要被提取的图像数据矩形区域的宽度。
sh:将要被提取的图像数据矩形区域的⾼度。
在获取到图⽚的像素数据之后,我们就可以对获取的像素数据进⾏处理,⽐如进⾏灰度化或反⾊处理。当完成处理后,若要在页⾯上显⽰处理效果,则我们需要利⽤ CanvasRenderingContext2D 提供的另⼀个 API —— putImageData。
该 API 是 Canvas 2D API 将数据从已有的 ImageData 对象绘制到位图的⽅法。如果提供了⼀个绘制过的矩形,则只绘制该矩形的像素。此⽅法不受画布转换矩阵的影响。putImageData ⽅法的语法如下:
void ctx.putImageData(imagedata, dx, dy);void ctx.putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
相应的参数说明如下:
imageData: ImageData ,包含像素值的数组对象。
dx:源图像数据在⽬标画布中的位置偏移量(x 轴⽅向的偏移量)。
dy:源图像数据在⽬标画布中的位置偏移量(y 轴⽅向的偏移量)。
dirtyX(可选):在源图像数据中,矩形区域左上⾓的位置。默认是整个图像数据的左上⾓(x 坐标)。
dirtyY(可选):在源图像数据中,矩形区域左上⾓的位置。默认是整个图像数据的左上⾓(y 坐标)。
dirtyWidth(可选):在源图像数据中,矩形区域的宽度。默认是图像数据的宽度。
dirtyHeight(可选):在源图像数据中,矩形区域的⾼度。默认是图像数据的⾼度。
介绍完相关的 API,下⾯我们来举⼀个实际例⼦:
html> 图⽚反⾊和灰度化处理
反⾊灰度化
需要注意的在调⽤ getImageData ⽅法获取图⽚像素数据时,你可能会遇到跨域问题,⽐如:
Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
对于这个问题,你可以阅读 「张鑫旭」 ⼤神 “解决canvas图⽚getImageData,toDataURL跨域问题” 这⼀篇⽂章。
3.6 如何实现图⽚隐写
「隐写术是⼀门关于信息隐藏的技巧与科学,所谓信息隐藏指的是不让除预期的接收者之外的任何⼈知晓信息的传递事件或者信息的内容。」 隐写术的英⽂叫做 Steganography,来源于特⾥特⽶乌斯的⼀本讲述密码学与隐写术的著作 Steganographia,该书书名源于希腊语,意为 “隐秘书写”。
⽬前有多种⽅案可以实现图⽚隐写,以下是⼏种常见的⽅案:
附加式的图⽚隐写;
基于⽂件结构的图⽚隐写;
基于 LSB 原理的图⽚隐写;
基于 DCT 域的 JPG 图⽚隐写;
数字⽔印的隐写;
图⽚容差的隐写。
篇幅有限,这⾥我们就不继续展开,分别介绍每种⽅案。
本篇已完结
推荐JavaScript经典实例学习资料⽂章
《推荐10个常⽤的图⽚处理⼩帮⼿(上)「值得收藏」》
《JavaScript 中ES6代理的实际⽤例》
《12 个实⽤的前端开发技巧总结》
《⼀⽂带你搞懂搭建企业级的 npm 私有仓库》
《教你如何使⽤内联框架元素 IFrames 的沙箱属性提⾼安全性?》
《细说前端开发UI公共组件的新认识「实践」》
《细说DOM API中append和appendChild的三个不同点》
《细品淘系⼤佬讲前端新⼈如何上王者「⼲货」》
《⼀⽂带你彻底解决背景跟随弹窗滚动问题「⼲货」》
《推荐常⽤的5款代码⽐较⼯具「值得收藏」》
《Node.js实现将⽂字与图⽚合成技巧》
《爱奇艺云剪辑Web端的技术实现》
《我再也不敢说我会写前端 Button组件「实践」》
《NodeX Component - 滴滴集团 Node.js ⽣态组件体系「实践」》
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论