PhotoDithering

This commit is contained in:
jessikitty committed 2026-09-16 15:01:06 +10:00
1 parent 3b2a399769
commit d998b6731e
7 files changed
+304 -3

No files matched your search

+44 -2
View File
@@ -392,12 +392,14 @@ router.patch('/sites/:id', (req, res) => {
const badge = req.body?.badge || {};
const branding = req.body?.branding || {};
const printerCfg = req.body?.printer || {};
const photoCfg = req.body?.photo || {};
db.prepare(
`UPDATE sites SET name = ?, slug = ?, active = ?, badge_enabled = ?, badge_width_mm = ?,
badge_height_mm = ?, badge_show_photo = ?, badge_accent = ?, badge_note = ?,
colour_brand = ?, colour_signout = ?, colour_page = ?, colour_text = ?,
banner_height = ?, banner_align = ?, printer_enabled = ?, printer_host = ?,
printer_port = ?, printer_model = ?, printer_rotate = ?, printer_label = ? WHERE id = ?`
printer_port = ?, printer_model = ?, printer_rotate = ?, printer_label = ?,
photo_mode = ?, photo_threshold = ?, photo_contrast = ? WHERE id = ?`
).run(
clean(req.body?.name ?? site.name, 100) || site.name,
req.body?.slug ? uniqueSlug(req.body.slug, site.id) : site.slug,
@@ -435,7 +437,16 @@ router.patch('/sites/:id', (req, res) => {
: site.printer_rotate,
printerCfg.label !== undefined
? (Object.hasOwn(printer.ROLL_TYPES, printerCfg.label) ? printerCfg.label : '62')
: site.printer_label
: site.printer_label,
photoCfg.mode !== undefined
? (Object.hasOwn(printer.PHOTO_MODES, photoCfg.mode) ? photoCfg.mode : 'dither')
: site.photo_mode,
photoCfg.threshold !== undefined
? Math.min(95, Math.max(5, Number(photoCfg.threshold) || 50))
: site.photo_threshold,
photoCfg.contrast !== undefined
? Math.min(100, Math.max(-100, Number(photoCfg.contrast) || 0))
: site.photo_contrast
, site.id);
res.json(shapeSite(db.prepare('SELECT * FROM sites WHERE id = ?').get(site.id)));
@@ -561,6 +572,37 @@ router.post('/visits/:id/print', async (req, res) => {
}
});
/** The same photo at several halftone settings, to choose between by eye. */
router.get('/sites/:id/photo-preview', async (req, res) => {
const site = db.prepare('SELECT * FROM sites WHERE id = ?').get(req.params.id);
if (!site) return res.status(404).send('Not found.');
// Whatever real photo is closest to hand: the most recent visit at this site,
// then any stored recurring visitor photo.
const recent =
db
.prepare(
'SELECT photo_path FROM visits WHERE site_id = ? AND photo_path IS NOT NULL ORDER BY id DESC LIMIT 1'
)
.get(site.id) ||
db.prepare('SELECT photo_path FROM frequent_visitors WHERE photo_path IS NOT NULL LIMIT 1').get();
const overrides = {
photo_mode: req.query.mode || site.photo_mode,
photo_threshold: req.query.threshold || site.photo_threshold,
photo_contrast: req.query.contrast || site.photo_contrast,
};
try {
const png = await printer.photoPreviewPng(recent?.photo_path || null, overrides);
res.setHeader('Content-Type', 'image/png');
res.setHeader('Cache-Control', 'no-store');
res.send(png);
} catch (err) {
res.status(500).send(`Could not render the preview: ${err.message}`);
}
});
router.get('/sites/:id/badge-preview', (req, res) => {
const site = db.prepare('SELECT * FROM sites WHERE id = ?').get(req.params.id);
if (!site) return res.status(404).send('Not found.');