Кодирование файлов в Node.js
Хелперы из hazehash/node читают файл изображения или буфер, декодируют его через sharp и кодируют пиксели. Это способ хешировать картинки на диске, не пиша самому код чтения пикселей.
import { encodeFile, encodeFileToString, encodeFileDetailed } from 'hazehash/node'sharp это необязательная peer-зависимость (0.33 или новее), поэтому установите её там, где используете эти хелперы:
npm install --save-dev sharpБез неё хелперы бросают PlaceholderError с кодом InvalidInput и сообщением, которое объясняет, как установить sharp. Точкам входа ядра он никогда не нужен.
Перед кодированием изображение переводится в sRGB и поворачивается по EXIF-ориентации, поэтому хеш соответствует тому, что показывает браузер. Все хелперы принимают одни и те же два аргумента:
pathOrBuffer
string | Uint8Array
Путь к файлу изображения или байты закодированного изображения (JPEG, PNG, WebP, AVIF, GIF и остальные форматы, которые читает sharp).
options
EncodeOptions · необязательно
Те же опции, что у encode(): budget, profile, alpha, analysisSize и weights.
Получение строки
encodeFileToString(pathOrBuffer, options?)
Promise<string>
Возвращает хеш в base64url.
import { encodeFileToString } from 'hazehash/node'
const hash = await encodeFileToString('photo.jpg', { budget: 24 })
// "Ec7UwRWKIv5znmt3XYLUF5zBSYmAo0Wr"Получение байтов
encodeFile(pathOrBuffer, options?)
Promise<Uint8Array>
Возвращает сырые байты хеша, для бинарной колонки.
import { encodeFile } from 'hazehash/node'
const bytes = await encodeFile('photo.jpg')
bytes.length // 28Получение размера вместе с хешем
encodeFileDetailed(pathOrBuffer, options?)
Promise<EncodedFile>
Возвращает байты, строку и размер изображения в пикселях в том виде, как оно показывается, то есть после поворота по EXIF. Это функция, на которой построена команда hazehash encode, и способ сохранить настоящие размеры рядом с хешем.
import { encodeFileDetailed } from 'hazehash/node'
const { hash, bytes, width, height } = await encodeFileDetailed('photo.jpg')
// hash: "Ed7UwRWKKv5znm6a7sC1tziHDNpMuCikxrYpIg", width: 1280, height: 959Результат имеет такую форму:
interface EncodedFile {
bytes: Uint8Array // байты хеша
hash: string // хеш в base64url
width: number // размер в пикселях, как показывается
height: number
}Хеширование папки
Хелперы хешируют одну картинку за вызов. Для папки обойдите файлы циклом; сам энкодер занимает несколько миллисекунд, так что время уходит на декодирование изображения:
import { readdir, writeFile } from 'node:fs/promises'
import { extname, join } from 'node:path'
import { encodeFileToString } from 'hazehash/node'
const dir = './images'
const hashes: Record<string, string> = {}
for (const name of await readdir(dir)) {
if (['.jpg', '.jpeg', '.png', '.webp'].includes(extname(name).toLowerCase())) {
hashes[name] = await encodeFileToString(join(dir, name), { budget: 24 })
}
}
await writeFile('hashes.json', JSON.stringify(hashes, null, 2))Для разовой задачи то же делает команда без кода: npx hazehash encode ./images -f json -o hashes.json. В Nuxt модуль генерирует и кэширует хеши при сборке.