Home Manual Reference Source

src/utils/pngUtils.js

import PNG from "pngjs";
import fs from "fs";
import palette from "get-rgba-palette";

/**
 * Module with utility functions for .png files
 * @module PngUtils
 */

module.exports = {
  /**
   * Checks if percent of black pixels in image is above a threshold
   * @param {String} imagePath - Path to image file (must be .png)
   * @param {Integer} threshold - Percent (as integer) of how black image is
   * @returns  {Boolean} True if result is above threshold, false if below.
   * @example imImageAboveBlackThreshold('./tempShots/test.png', 95)
   * @example
   * // Returns...
   * true
   */
  isImageAboveBlackThreshold: (imagePath, threshold) => {
    const blackPercentage = _getDominantBlackPercentage(imagePath);
    return blackPercentage * 100 > threshold;
  }
};

/**
   * Determines if a color is considered black. 
   * RGB value < 25 is considered black.
   * @param {Array} color - Array af RGB values (such as [10, 25, 120])
   * @returns  {Boolean} True if each value in RGB array is under 25.
   * @private
   * @example _consideredBlack([45, 45, 100])
   * @example
   * // Returns...
   * false
   */
function _consideredBlack(color) {
  return color.every(value => value < 25);
}

/**
   * Gets percentage of pixels considered black in image
   * @param {String} imagePath - Path to image file (must be .png)
   * @returns  {Integer} Percentage of black pixels in image
   * @private
   * @example _getDominantBlackPercentage('./tempShots/test.png')
   * @example
   * // Returns...
   * .35
   */
function _getDominantBlackPercentage(imagePath) {
  const data = fs.readFileSync(imagePath);
  const png = PNG.sync.read(data);
  const colors = palette.bins(png.data, 10);
  const dominantColor = colors[0];

  if (_consideredBlack(dominantColor.color)) {
    return dominantColor.amount;
  }
  return 0;
}