For my first PyPortal project (and my first CircuitPlaygound project), I wanted to display images from the site ThisPersonDoesNotExist.com, which displays random AI generated images of people who actually do not exist in real life, hence the name, “Ghost Frame”. The site generates a new JPEG image about every 2 seconds. So the idea was to download this JPEG file from the site and display it on the PyPortal. The first problem: the PyPortal does not natively support JPEG images. It does support BMP images but JPEG decompression is quite computationally intensive for CircuitPython. JPEG decompression may have native support in the future but not in its current release.
To work around this issue, an idea mentioned by Lady Ada herself on GitHub was to convert the JPEG file to BMP. With a bit of research, I wrote a JPEG to BMP converter in PHP. This is a web service written in less than 10 lines of PHP code. It not only converts JPEG images to BMP images, but it also scales the BMP image to fit the PyPortal’s screen dimensions of 320 x 240 pixels. You will need a website running PHP (or have a really good friend that has one) in order to run this web service.
The next hurdle was downloading the converted JPEG image to the PyPortal for display. This required storing the image file temporarily on the PyPortal before displaying it, since the image was too big to fit in memory. I first came up with using an SD card in the PyPortal’s SD card slot and storing the image there. The same image file is written over and over each time a new image is downloaded. This option works, but you need an SD card to use with the PyPortal. I also wanted to try downloading the image file directly to the CircuitPython’s 8MB filesystem. This is a bit tricky since the filesystem is also available to the host computer the CircuitPython device is plugged into, and having two different processors writing to the same filesystem is a disaster waiting to happen.
What is needed is a boot.py file, which tells the PyPortal if the filesystem is read-only or read-write. This check is done when the PyPortal boots up. The mode is toggled by a female/female jumper wire on the D4 connector. Connect the jumper wire and it is read-write for CircuitPython. Remove the jumper wire and it is read-write for the host operating system. So you need the operating system to have write access to install and modify the Ghost Frame code in code.py. Once you have that working, you can insert the wire to allow the PyPortal to download the image directly to the CircuitPython file system. An extra bonus is that you can view the most recent image directly from the host computer.
The “Ghost Frame” is not just limited to people. The site, ThisCatDoesNotExist.com displays AI generated images of cats. You can select in the code if you want people ghosts or cat ghosts to appear in the frame.
The code for the “Ghost Frame” is open source and is available on GitHub. For future development, it would be nice to take advantage of the touch screen and be able to select on the screen to show people or cats.
What ghosts will appear in your “Ghost Frame”?
Additional details of this project are available on my blog site.