Image – what is the size

A Node module to get the size of any image file.

git:https://github.com/image-size/image-size

The source code parsing

First of all, sort out a flow chart to analyze a picture.

The nutrients that are absorbed

  1. Nodejs package loading mechanism

    bin/image-size.js

    var imageSize = require('.. ');
    Copy the code

    package.json

        "main": "lib/index.js"
    Copy the code

    require(‘.. ‘) which file is loaded?

    Nodejs’ package loading mechanism makes ‘.. ‘parse into’… /’, then try to fetch the main field from package.json as the entry point for loading the file, so load lib/index.js.

  2. Detect user input

        var files = process.argv.slice(2);
        if(! files.length) { console.error('Usage: image-size image1 [image2] [image3] ... ');
          process.exit(-1);
        }
    Copy the code

    Take input from the user through process.argv.slice(2) and prompt and assist in the absence of input from the user.

  3. Checks whether the current file exists

        fs.existsSync(path.resolve(image)
    Copy the code

    Convert the image’s path to an absolute path and call the fs.existssync method.

    Although fs.exists() is deprecated, fs.existssync () is not. – nodejs document

  4. Read files into buffer

    • Asynchronous transfer
        function asyncFileToBuffer (filepath, callback) {
          // open the file in read only mode
          fs.open(filepath, 'r'.function (err, descriptor) {
            if (err) { return callback(err); }
            fs.fstat(descriptor, function (err, stats) {
              if (err) { return callback(err); }
              var size = stats.size;
              if (size <= 0) {
                return callback(new Error('File size is not greater than 0 —— ' + filepath));
              }
              var bufferSize = Math.min(size, MaxBufferSize);
              var buffer = new Buffer(bufferSize);
              // read first buffer block from the file, asynchronously
              fs.read(descriptor, buffer, 0, bufferSize, 0, function (err) {
                if (err) { return callback(err); }
                // close the file, we are done
                fs.close(descriptor, function (err) {
                  callback(err, buffer);
                });
              });
            });
          });
        }
    Copy the code
    • Synchronous conversion
        function syncFileToBuffer (filepath) {
          // read from the file, synchronously
          var descriptor = fs.openSync(filepath, 'r');
          var size = fs.fstatSync(descriptor).size;
          var bufferSize = Math.min(size, MaxBufferSize);
          var buffer = new Buffer(bufferSize);
          fs.readSync(descriptor, buffer, 0, bufferSize, 0);
          fs.closeSync(descriptor);
          return buffer;
        }
    Copy the code
    1. Start by opening the file fs.open
    2. Get file information fs.fstat
    3. If so, read the file fs.read
    4. When successful, close the file stream fs.close

    The authors limit the size of the buffer, otherwise it would be more convenient to use fs.createreadstream.

  5. Detect the type of image

    • There are extension classes in all formats in the lib/types folder and uniformly loaded and imported in the lib/types.js file

      var typeHandlers = {
        bmp: require('./types/bmp'),
        cur: require('./types/cur'),
        dds: require('./types/dds'),
        gif: require('./types/gif'),
        icns: require('./types/icns'),
        ico: require('./types/ico'),
        jpg: require('./types/jpg'),
        png: require('./types/png'),
        psd: require('./types/psd'),
        svg: require('./types/svg'),
        tiff: require('./types/tiff'),
        webp: require('./types/webp'),};Copy the code

      You can have a class that does things like multi-file imports.

    • All format extension classes export methods named ‘detect’ and ‘calculate’

      lib/detector.js

          module.exports = function (buffer, filepath) {
            var type, result;
            for (type in typeHandlers) {
              result = typeHandlers[type].detect(buffer, filepath);
              if (result) {
                return type; }}};Copy the code

      Unified format extension class exported method name, easy to expand. When you extend images in different formats later, you only need to add the corresponding format extension class without changing the current code. (Closed for modifications open for extensions — OCP principle)

  6. Get information about the picture

    Different picture formats have different ways to obtain information. The knowledge involved here is a little deep. Here, we just record the ideas and make detailed inquiries when specific needs are made.

    • Read bytes based on buffer, read and retrieve the corresponding binary data information based on the format description.

    Record the difference between big-endian and small-endian reads:

    const buf = Buffer.from([0x12, 0x34, 0x56]); console.log(buf.readUInt16BE(0).toString(16)); // Prints: 1234 big end on right console.log(buf.readUint16le (0).toString(16)); Prints: 3412 small end is on the rightCopy the code
  7. Console. log outputs colored fonts

    When the results are finally returned, both the wide and high data are green. It turns out that console.log can set CSS styles.

    For example (you can type in Chrome developer mode to see the style)

         console.log( Hello '% c'.'color:red' )
    Copy the code

    All fonts after %c can be used with written CSS styles.

        console.log( 'Hello % C, did % C study today?'.'color:red' , 'color:yellow')
    Copy the code

    Use of multiple font styles

conclusion

Read the source code to broaden your horizons, but also to better learn NodeJS. Start with simple modules and gradually increase the difficulty to learn the author’s ideas and routines.

reference

  1. Nodejs document
  2. The size of the end