首页 web前端 js教程 node.js解决获取图片真实文件类型的问题_node.js

node.js解决获取图片真实文件类型的问题_node.js

May 16, 2016 pm 04:25 PM
node.js

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

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

复制代码 代码如下:

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相关的信息时,找到这篇文章:node.js module ranking>> (images)

然后筛选到一个模块“node-imageinfo”,写了一个例子进行测试(故意把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]     }
    else {
        if (buffer.readUInt32LE) {
            return buffer.readUInt32LE(offset);
        }
        value = buffer[offset] + (buffer[offset+1]     }
    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]     }
    else {
        if (buffer.readUInt16LE) {
            return buffer.readUInt16LE(offset);
        }
        value = buffer[offset] + (buffer[offset+1]     }
    return value;
}

function readBit(buffer, offset, bitOffset) {
    if (bitOffset > 7) {
        offset += Math.floor(bitOffset / 8);
        bitOffset = bitOffset % 8;
    }

    var b = buffer[offset];
    if (bitOffset         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         var b = readBit(buffer, offset, bitOffset + i);
        if (i>0 && (bitLen - i) % 8 == 0) {
            bytes.push(val);
            val = 0;
        }
        val         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         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         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;
};

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1664
14
CakePHP 教程
1423
52
Laravel 教程
1319
25
PHP教程
1269
29
C# 教程
1248
24
图文详解Node V8引擎的内存和GC 图文详解Node V8引擎的内存和GC Mar 29, 2023 pm 06:02 PM

本篇文章带大家深入了解NodeJS V8引擎的内存和垃圾回收器(GC),希望对大家有所帮助!

一文聊聊Node中的内存控制 一文聊聊Node中的内存控制 Apr 26, 2023 pm 05:37 PM

基于无阻塞、事件驱动建立的Node服务,具有内存消耗低的优点,非常适合处理海量的网络请求。在海量请求的前提下,就需要考虑“内存控制”的相关问题了。 1. V8的垃圾回收机制与内存限制 Js由垃圾回收机

聊聊如何选择一个最好的Node.js Docker镜像? 聊聊如何选择一个最好的Node.js Docker镜像? Dec 13, 2022 pm 08:00 PM

选择一个Node​的Docker镜像看起来像是一件小事,但是镜像的大小和潜在漏洞可能会对你的CI/CD流程和安全造成重大的影响。那我们如何选择一个最好Node.js Docker镜像呢?

Node.js 19正式发布,聊聊它的 6 大特性! Node.js 19正式发布,聊聊它的 6 大特性! Nov 16, 2022 pm 08:34 PM

Node 19已正式发布,下面本篇文章就来带大家详解了解一下Node.js 19的 6 大特性,希望对大家有所帮助!

深入聊聊Node中的File模块 深入聊聊Node中的File模块 Apr 24, 2023 pm 05:49 PM

文件模块是对底层文件操作的封装,例如文件读写/打开关闭/删除添加等等 文件模块最大的特点就是所有的方法都提供的**同步**和**异步**两个版本,具有 sync 后缀的方法都是同步方法,没有的都是异

一起聊聊Node中的事件循环 一起聊聊Node中的事件循环 Apr 11, 2023 pm 07:08 PM

事件循环是 Node.js 的基本组成部分,通过确保主线程不被阻塞来实现异步编程,了解事件循环对构建高效应用程序至关重要。下面本篇文章就来带大家深入了解Node中的事件循环 ,希望对大家有所帮助!

聊聊用pkg将Node.js项目打包为可执行文件的方法 聊聊用pkg将Node.js项目打包为可执行文件的方法 Dec 02, 2022 pm 09:06 PM

​如何用pkg打包nodejs可执行文件?下面本篇文章给大家介绍一下使用pkg将Node项目打包为可执行文件的方法,希望对大家有所帮助!

node无法用npm命令怎么办 node无法用npm命令怎么办 Feb 08, 2023 am 10:09 AM

node无法用npm命令是因为没有正确配置环境变量,其解决办法是:1、打开“系统属性”;2、找到“环境变量”->“系统变量”,然后编辑环境变量;3、找到nodejs所在的文件夹;4、点击“确定”即可。

See all articles