博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
node.js获取图片文件的真实类型
阅读量:7087 次
发布时间:2019-06-28

本文共 6718 字,大约阅读时间需要 22 分钟。

遇到一个需求:假定有一个图片文件,真实的类型为jpg,而有人偷懒把jpg直接复制一张,存为同名的png文件,这样在as3读取文件时不会遇到问题,但手机c++在读取文件时却遇到问题了 - -!

 

现在就需要写一个程序,遍历所有文件夹下的文件,查找文件格式“不正常”的文件。我们的资源主要是gif、png、jpg,最开始,我到网上找到一篇文章:,然后读取文件二进制的头信息,获取其真实的文件类型,对与通过后缀名获得的文件类型进行比较。

var fd = fs.openSync(new_file_path, 'r'); var buffer = new Buffer(8); var mineType = mime.lookup(new_file_path); var fileType = mime.extension(mineType); fs.readSync(fd, buffer, 0, 8, 0); var newBuf = buffer.slice(0, 4); var head_1 = newBuf[0].toString(16); var head_2 = newBuf[1].toString(16); var head_3 = newBuf[2].toString(16); var head_4 = newBuf[3].toString(16); var head_iden = head_1 + head_2; var tempFileType = FILE_TYPE_CONFIG[head_iden]; if (!tempFileType) {
head_iden += head_3; tempFileType = FILE_TYPE_CONFIG[head_iden]; if (!tempFileType) {
var msg = "Unknow fileType " + new_file_path + '-' + fileType; showLog(msg); continue; } } if (tempFileType != fileType) {
var msg = "Error fileType" + new_file_path + '-' + fileType + '|' + tempFileType + '--正确的图像文件格式'; showLog(msg); g_errorFileTypArr.push(msg); }

后来搜索node image相关的信息时,找到这篇文章:

然后筛选到一个模块“”,写了一个例子进行测试(故意把jpg文件直接修改后缀名为png):

 

它的源码,有兴趣可以研究一下:

function readUInt32(buffer, offset, bigEndian) {
if (buffer.readUInt32) {
return buffer.readUInt32(offset, bigEndian); } var value; if (bigEndian) {
if (buffer.readUInt32BE) {
return buffer.readUInt32BE(offset); } value = (buffer[offset] << 24) + (buffer[offset+1] << 16) + (buffer[offset+2] << 8) + buffer[offset+3]; } else {
if (buffer.readUInt32LE) {
return buffer.readUInt32LE(offset); } value = buffer[offset] + (buffer[offset+1] << 8) + (buffer[offset+2] << 16) + (buffer[offset+3] << 24); } return value; } function readUInt16(buffer, offset, bigEndian) {
if (buffer.readUInt16) {
return buffer.readUInt16(offset, bigEndian); } var value; if (bigEndian) {
if (buffer.readUInt16BE) {
return buffer.readUInt16BE(offset); } value = (buffer[offset] << 8) + buffer[offset+1]; } else {
if (buffer.readUInt16LE) {
return buffer.readUInt16LE(offset); } value = buffer[offset] + (buffer[offset+1] << 8); } return value; } function readBit(buffer, offset, bitOffset) {
if (bitOffset > 7) {
offset += Math.floor(bitOffset / 8); bitOffset = bitOffset % 8; } var b = buffer[offset]; if (bitOffset < 7) {
b >>>= (7 - bitOffset); } var val = b & 0x01; return val; } function readBits(buffer, offset, bitOffset, bitLen, signed) {
var val = 0; var neg = false; if (signed) {
if (readBit(buffer, offset, bitOffset) > 0) {
neg = true; } bitLen--; bitOffset++; } var bytes = []; for (var i = 0; i < bitLen; i++) {
var b = readBit(buffer, offset, bitOffset + i); if (i>0 && (bitLen - i) % 8 == 0) {
bytes.push(val); val = 0; } val <<= 1; val |= b; } bytes.push(val); val = new Buffer(bytes); val.negative = neg?true:false; return val; } function imageInfoPng(buffer) {
var imageHeader = [0x49, 0x48, 0x44, 0x52], pos = 12; if (!checkSig(buffer, pos, imageHeader)) {
return false; } pos += 4; return {
type: 'image', format: 'PNG', mimeType: 'image/png', width: readUInt32(buffer, pos, true), height: readUInt32(buffer, pos+4, true), }; } function imageInfoJpg(buffer) {
var pos = 2, len = buffer.length, sizeSig = [0xff, [0xc0, 0xc2]]; while (pos < len) {
if (checkSig(buffer, pos, sizeSig)) {
pos += 5; return {
type: 'image', format: 'JPG', mimeType: 'image/jpeg', width: readUInt16(buffer, pos+2, true), height: readUInt16(buffer, pos, true), }; } pos += 2; var size = readUInt16(buffer, pos, true); pos += size; } } function imageInfoGif(buffer) {
var pos = 6; return {
type: 'image', format: 'GIF', mimeType: 'image/gif', width: readUInt16(buffer, pos, false), height: readUInt16(buffer, pos+2, false), }; } function imageInfoSwf(buffer) {
var pos = 8, bitPos = 0, val; if (buffer[0] === 0x43) {
try {
// If you have zlib available ( npm install zlib ) then we can read compressed flash files buffer = require('zlib').inflate(buffer.slice(8, 100)); pos = 0; } catch (ex) {
// Can't get width/height of compressed flash files... yet (need zlib) return {
type: 'flash', format: 'SWF', mimeType: 'application/x-shockwave-flash', width: null, height: null, } } } var numBits = readBits(buffer, pos, bitPos, 5)[0]; bitPos += 5; val = readBits(buffer, pos, bitPos, numBits, true); var xMin = (numBits > 9 ? readUInt16(val, 0, true) : val[0]) * (val.negative ? -1 : 1); bitPos += numBits; val = readBits(buffer, pos, bitPos, numBits, true); var xMax = (numBits > 9 ? readUInt16(val, 0, true) : val[0]) * (val.negative ? -1 : 1); bitPos += numBits; val = readBits(buffer, pos, bitPos, numBits, true); var yMin = (numBits > 9 ? readUInt16(val, 0, true) : val[0]) * (val.negative ? -1 : 1); bitPos += numBits; val = readBits(buffer, pos, bitPos, numBits, true); var yMax = (numBits > 9 ? readUInt16(val, 0, true) : val[0]) * (val.negative ? -1 : 1); return {
type: 'flash', format: 'SWF', mimeType: 'application/x-shockwave-flash', width: Math.ceil((xMax - xMin) / 20), height: Math.ceil((yMax - yMin) / 20), }; } function checkSig(buffer, offset, sig) {
var len = sig.length; for (var i = 0; i < len; i++) {
var b = buffer[i+offset], s = sig[i], m = false; if ('number' == typeof s) {
m = s === b; } else {
for (var k in s) {
var o = s[k]; if (o === b) {
m = true; } } } if (!m) {
return false; } } return true; } module.exports = function imageInfo(buffer, path) {
var pngSig = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; var jpgSig = [0xff, 0xd8, 0xff]; var gifSig = [0x47, 0x49, 0x46, 0x38, [0x37, 0x39], 0x61]; var swfSig = [[0x46, 0x43], 0x57, 0x53]; if (checkSig(buffer, 0, pngSig)) return imageInfoPng(buffer); if (checkSig(buffer, 0, jpgSig)) return imageInfoJpg(buffer); if (checkSig(buffer, 0, gifSig)) return imageInfoGif(buffer); if (checkSig(buffer, 0, swfSig)) return imageInfoSwf(buffer); return false; };

转载地址:http://edfql.baihongyu.com/

你可能感兴趣的文章
pyqt声音输入
查看>>
FMX 模态窗体
查看>>
使用storyboard实现页面跳转,简单的数据传递
查看>>
有些事明显对自己有益,为什么却无法去做?
查看>>
IOS开发基础知识--碎片30
查看>>
C语言编程规范—命名规则
查看>>
批处理-剪切文件夹到指定目录
查看>>
java POi excel 写入大批量数据
查看>>
关于子类对象的构造函数和父类构造函数的执行顺序
查看>>
.NET Core Web 应用部署到 Docker 中运行
查看>>
Saltstack-API(十二)
查看>>
Asp.net Boilerplate源码中NotNullAttribute的用处
查看>>
javascript继承
查看>>
待处理
查看>>
linux下在root用户登陆状态下,以指定用户运行脚本程序实现方式
查看>>
FB面经Prepare: Merge K sorted Array
查看>>
模拟链表
查看>>
C#中使用SendMessage在进程间传递数据的实例
查看>>
ADT Android Development Tools
查看>>
OpenGL ES 简单教程
查看>>