您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
coay(推荐10个常用的图片处理小帮手(下))
图片,数据,图像coay(推荐10个常用的图片处理小帮手(下))
发布时间:2016-12-08加入收藏来源:互联网点击:
-
三、阿宝哥有话说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);//=> true
「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,我们也可以方便的实现图片本地预览功能,具体代码如下:
<input type="file" accept="image/*" onchange="loadFile(event)"><img id="output"/><script> const loadFile = function(event) { const reader = new FileReader(); reader.onload = function(){ const output = document.querySelector('output'); output.src = reader.result; }; reader.readAsDataURL(event.target.files[0]); };</script>
在完成本地图片预览之后,可以直接把图片对应的 Data URLs 数据提交到服务器。针对这种情形,服务端需要做一些相关处理,才能正常保存上传的图片,这里以 Express 为例,具体处理代码如下:
const app = require('express')();app.post('/upload', function(req, res){ let imgData = req.body.imgData; // 获取POST请求中的base64图片数据 let base64Data = imgData.replace(/^data:image/w ;base64,/, ""); let dataBuffer = Buffer.from(base64Data, 'base64'); fs.writeFile("image.png", dataBuffer, function(err) { if(err){ res.send(err); }else{ res.send("图片上传成功!"); } });});
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 = document.createElement("canvas"); let img = document.createElement("img"); img.crossOrigin = "anonymous"; return new Promise((resolve, reject) => { img.src = base64; img.onload = () => { let targetWidth, targetHeight; if (img.width > MAX_WIDTH) { targetWidth = MAX_WIDTH; targetHeight = (img.height * MAX_WIDTH) / img.width; } else { targetWidth = img.width; targetHeight = img.height; } canvas.width = targetWidth; canvas.height = targetHeight; let ctx = canvas.getContext("2d"); ctx.clearRect(0, 0, targetWidth, targetHeight); // 清除画布 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); let imageData = canvas.toDataURL(mimeType, quality / 100); resolve(imageData); }; });}
对于返回的 Data URL 格式的图片数据,为了进一步减少传输的数据量,我们可以把它转换为 Blob 对象:
function dataUrlToBlob(base64, mimeType) { let bytes = window.atob(base64.split(",")[1]); let ab = new ArrayBuffer(bytes.length); let ia = new Uint8Array(ab); for (let i = 0; i < bytes.length; i ) { ia[i] = bytes.charCodeAt(i); } return new Blob([ab], { type: mimeType });}
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |