Party printer project

This was made as a selfie both at a party (at the height appropriate for an erotic party, in fact) with the idea that it was just high quality enough to be recognizable but not very identifying.
Also easy and cheap to run - thermal rolls are small, cost very little, and requires no ink, much of which also make it minimally wasteful.
The printer is a thermal Point-of-Sale (POS) printer, a.k.a. receipts printer at a checkout.
It turns most of these receipt printers do around 200dpi. Higher resolutions exist, but aren't all that common, as it's not that useful for receipts, and that is their only purpose. Still, 200dpi is can do more than letters and barcodes, so with some care it can do a decent image.
In the wooden box
- A thermal printer meant for point of sale (receipts)
- Currently a HS802UL (USB and network), I previously broke a Star TSP600 (serial)
- which is one with a cutter, though tear-off also has its charm
- I would recommend trying to find one with network interface or USB, because just serial interface is rather slower, and potentially finicky (particularly if you don't have proper flow control. Whereas networking comes down to 'open TCP connection and send data and be done with it')
- a Raspberry Pi and it power supply
- the image processing is easier to do when you have some memory and some CPU (a uC would be harder)
- an access point and its power supply
- Using an old AP makes it easy for this to not depend on futzing with the environment's WiFi
- a power strip
- some creatively positioned plastic and wood to separate and positioning of all of that


Alongside:
- A WiFi-capable IP camera
- Here a DCS-930L, but any should do, as long as it exposes an URL to fetch the current image from without too much trouble
The code
As this IP camera has has a URL that gives the latest image, capturing from the IP camera can continuous at a moderate rate, essentially slow video, one image at a time.
When a sudden increase in brightness is detected between images, we start collecting collect candidate images for a second or so, and choose the best (e.g. by amount of apparent sharpness in the image, and not washed out).
- The trigger is done based on brightness because it means we can trigger without any additional wiring or communication.
- The mentioned button just has to light a lamp next to the camera. and the Pi does its work purely based on the images.
- Yes, this is imperfect in the very dark (anything light would trigger it), or the very bright (nothing might). Putting one curtain around it helps that a lot.
- It also means it's much easier to put the printer box in a separate, safer place.
- Even without multithreading, so the image processing interrupts our fetching every frame, we still get a few frames per second, which is more than enough.
Various POS printers speak their own proprietary and more capable protocol,
but most should be able to speak ESC/POS, a relatively basic protocol,
which means fairly simple code should work for most POS printers.
Say, the decoration below is mostly just consists of "send string, send cut command, repeat".
The conversion to an image is slightly more involved, because aside from the massaging the image size and orientation, there's also conversion into a 1-bit image with considerations like brightness and dithering, then packing it into bits one a row at a time.
I realize now I never posted the code. Working on it.