Fire up a Terminal window and cd to the directory where you saved the visualize-frame-colors.js file
This script requires Color Thief. To install, cd into your project’s directory and run npm i colorthief --save-dev in your terminal. I try to avoid using third-party libraries, but I ended up taking a shortcut for this project.
Edit all constants to fit your needs
Run node visualize-frame-colors.js in your terminal
Read out the results returned in the terminal
import fs from 'fs'
import ColorThief from 'colorthief';
// Toggle whether diff data should be generated and exported to JSON. This is an expensive operation, so it's helpful to set this to false if you're only tuning the visuals
const EXPORT_JSON = true
// The directory where the frame images exist
const SEQUENCE_DIRECTORY_PATH = '../../../../../Movies/the-dark-knight'
// The naming of each frame (including separator). The script depends on a sequential number for each image with no leading zeros. Example: `frame_1, frame_2, frame_3`
const SEQUENCE_IMAGE_FILE_PREFIX = 'the_dark_knight_'
// The image type. I've only tested this with jpg images
const SEQUENCE_IMAGE_EXTENSION = '.jpg'
// The frame to start with. This can be helpful if you want to isolate the visualization to specific areas of a sequence
const START_FRAME = 1
// The frame to end with. If set to `-1`, the script will run until there are no more frames to load
const END_FRAME = 95
// The name/location for the generated JSON file containing all frame diff values. This JSON file is used to generate the final visualization
const EXPORT_JSON_PATH = './colors.json'
// The length of each sampled frame
const SAMPLED_FRAME_HEIGHT = 200
// The name/location for the generated SVG file
const EXPORT_SVG_PATH = './colors.svg'
async function sampleColors(imagePath, imageName, startFrame, endFrame, imageExtension, jsonFilePath) {
let colors = []
let frame = startFrame
let img = imagePath + '/' + imageName + frame + imageExtension;
while((frame < endFrame || endFrame === -1) && fs.existsSync(img)) {
console.log(frame)
var color = await getFrameColor(img)
colors.push(color)
frame++
img = imagePath + '/' + imageName + frame + imageExtension;
}
fs.writeFileSync(jsonFilePath, JSON.stringify(colors))
}
function visualizeColors(colorData, frameHeight, svgFilePath) {
let svg = ''
for(var i = 0; i < colorData.length; i++) {
let color = colorData[i]
svg += ''
}
svg = ''
fs.writeFileSync(svgFilePath, svg)
}
async function getFrameColor(img) {
var color = await ColorThief.getColor(img)
return color;
}
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
async function generateColorTimeline(exportJSON, sequenceDirectory, sequenceFileName, startFrame, endFrame, imageExtension, jsonFilePath, frameHeight, svgFilePath) {
if(exportJSON) {
await sampleColors(sequenceDirectory, sequenceFileName, startFrame, endFrame, imageExtension, jsonFilePath)
}
let colorData = JSON.parse(fs.readFileSync(jsonFilePath))
visualizeColors(colorData, frameHeight, svgFilePath)
}
generateColorTimeline(
EXPORT_JSON,
SEQUENCE_DIRECTORY_PATH,
SEQUENCE_IMAGE_FILE_PREFIX,
START_FRAME,
END_FRAME,
SEQUENCE_IMAGE_EXTENSION,
EXPORT_JSON_PATH,
SAMPLED_FRAME_HEIGHT,
EXPORT_SVG_PATH
)