Node. js solves the problem of obtaining the actual file type of images. The node. js file type

Source: Internet
Author: User

Node. js solves the problem of obtaining the actual file type of images. The node. js file type

A requirement: Assume that there is an image file with the actual type of jpg, and someone is lazy to copy a jpg file directly and save it as a png file with the same name, in this way, as3 will not encounter problems when reading files, but c ++ will encounter problems when reading files --!

Now you need to write a program to traverse all the files in the folder and find the file in an "abnormal" format. Our resources are mainly gif, png, and jpg. At first, I found an article on the Internet: get the file type mime-type based on the binary stream and file header, then, read the binary header of the file to obtain its actual file type, and compare it with the file type obtained by the suffix.

Copy codeThe Code is as follows:
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 + '-- correct image file format ';
ShowLog (msg );

G_errorFileTypArr.push (msg );
}

When searching information about node image, find this article: node. js module ranking> (images)

Then, the module "node-imageinfo" is filtered out, and an example is written for testing (intentionally changing the jpg file suffix to png ):

Its source code can be studied as follows:


Copy codeThe Code is as follows:
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. Server Load balancer (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;
};

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.