You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.0 KiB
85 lines
2.0 KiB
// lib/canvas-image.js
|
|
// Copyright (C) 2022 Rob Colbert @[email protected]
|
|
// License: Apache-2.0
|
|
|
|
'use strict';
|
|
|
|
import path, { dirname } from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import fs from 'fs';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url)); // jshint ignore:line
|
|
|
|
import Jimp from 'jimp';
|
|
|
|
export default class CanvasImage {
|
|
|
|
static async getImages (redis) {
|
|
const images = [ ];
|
|
|
|
for (const key of await redis.keys('mpcvs:images:*')) {
|
|
const image = await redis.hgetall(key);
|
|
image.width = parseInt(image.width, 10);
|
|
image.height = parseInt(image.height, 10);
|
|
|
|
const tokens = key.split(':');
|
|
const id = tokens[tokens.length - 1];
|
|
images.push({ id, ...image });
|
|
}
|
|
|
|
return images;
|
|
}
|
|
|
|
constructor (id, name) {
|
|
this.id = id;
|
|
this.name = name;
|
|
this.idPrefix = this.id.slice(0, 4);
|
|
this.imagePath = path.resolve(__dirname, '..', 'images', this.idPrefix);
|
|
this._dirty = false;
|
|
}
|
|
|
|
get dirty ( ) { return this._dirty; }
|
|
|
|
get key ( ) { return `mpcvs:images:${this.id}`; }
|
|
|
|
get filename ( ) { return path.join(this.imagePath, `${this.id}.png`); }
|
|
|
|
get width ( ) { return this.image.bitmap.width; }
|
|
|
|
get height ( ) { return this.image.bitmap.height; }
|
|
|
|
create (width, height) {
|
|
this.image = new Jimp(width, height, 0xffffffff);
|
|
this._dirty = false;
|
|
}
|
|
|
|
async load ( ) {
|
|
try {
|
|
this.image = await Jimp.read(this.filename);
|
|
} catch (error) {
|
|
throw error;
|
|
} finally {
|
|
this._dirty = false;
|
|
}
|
|
}
|
|
|
|
async save ( ) {
|
|
const filename = this.filename;
|
|
console.log('writing image file', filename);
|
|
|
|
await fs.promises.mkdir(this.imagePath, { recursive: true });
|
|
await this.image
|
|
.deflateLevel(9)
|
|
.writeAsync(this.filename)
|
|
;
|
|
this._dirty = false;
|
|
}
|
|
|
|
setPixel (pixel) {
|
|
let idx = ((pixel.y * this.image.bitmap.width) + pixel.x) * 4;
|
|
this.image.bitmap.data[idx++] = pixel.r;
|
|
this.image.bitmap.data[idx++] = pixel.g;
|
|
this.image.bitmap.data[idx++] = pixel.b;
|
|
this._dirty = true;
|
|
}
|
|
}
|
|
|