FotoFika Art Baseball Cards

A screenshot of the art-based baseball cards.

Origin Story

The 2020 All Stars project1 is tied to the FotoFika site supporting photography faculty teaching online due to COVID. One of the concerns that came up in discussions was that this year’s graduating class wouldn’t be getting the personal connections that normally happen during exhibitions. That led to a discussion around Mike Mandel’s baseball card series for photographers back in the 1970s. The idea here is that we’ll generate baseball card-style images for graduating students. We’ll have a second portion where curators will be invited to comment on specific artist cards and their comments will be integrated into the card. Some portion of the cards will eventually be printed.2

Technical Stuff of Interest

The site ends up being interesting in a few ways. It’s running off a Google Form for image uploads etc. What you may or may not know already is that Google stopped letting you serve images from folders in any sort of decent way a while back.3 Sure you can do stuff like what the Awesome Table people suggest here but the image quality is garbage and I couldn’t get a number of the URL parameters to work correctly.

I opted to ask Jeff for an answer. He came up with the following Google Script which is pretty cool. It takes the file ID and gives you back the image as the kind base64 data string you could use as a data URI.

function getFileIds() {
  const folder = DriveApp.getFolderById('YOUR_ID_HERE')
  const files = folder.getFiles();
  const fileIds = []
  while (files.hasNext()) {
    let file =
  return fileIds

function getFileAsBytes(id) {
  const file = DriveApp.getFileById(id)
  const name = file.getName();
  const bytes = Utilities.base64Encode(file.getBlob().getBytes())
  return {
    "name" : name,
    "bytes": bytes


function doGet(e){
  if ( {
    const file = getFileAsBytes(
    return ContentService.createTextOutput(JSON.stringify(file)).setMimeType(ContentService.MimeType.JSON)
  } else {
  const fileIds = getFileIds();
  return ContentService.createTextOutput(JSON.stringify(fileIds)).setMimeType(ContentService.MimeType.JSON)

This all works and is really interesting to me in a variety of ways. The downside for us was that the image files increased pretty dramatically- something around triple the size. Since we were going to have an unknown number of images on there, I wanted to keep that side of things as economical as possible.

From Data String Back to Image

I started wandering around the Internet a bit looking for ways to save base64 strings as images and came across this Stack Overflow post doing exactly that. A tiny bit of tinkering led to the following PHP. It’ll take the endpoint4 Jeff’s Google Script generates and save that data to a local folder as a jpg. This got us back to the original file size with no issues. I find this to be kind of crazy.

$id = htmlspecialchars($_GET["id"]);
	$file_url = "".$id;
	$json = file_get_contents($file_url);
        $data = json_decode($json);
        $name = $data->name;
         echo $name;
        $clean_name = (explode( ' - ', $name)[0]);//nice clean image name so people don't go insane with what Google does there
        $clean_name = str_replace(' ', '', $clean_name);
        $clean_name = strtolower($clean_name);
        $file = 'data:image/jpeg;base64,' . strval($data->bytes);
    //thanks to
	list($type, $file) = explode(';', $file);
	list(, $file)      = explode(',', $file);
	$file = base64_decode($file);
	file_put_contents('work/' . $clean_name . '.jpg', $file);//saves to the particular folder

The rest of it is pretty standard Google Sheets to javascript/HTML/CSS. I may end up caching the JSON to make things a bit faster. I’m looking at lazy loading options etc. etc.

1 Warning. There is nudity. Art nudity.

2 I’m hazier about this side of things but I’m likely to be messing around with some InDesign workflow based on the data we have.

3 6 months? A year? What is time? Who cares? The past is the past.

4 A fancy name for a URL that does a trick for you. In this case it gives me a string of gibberish that is secretly an image.

Comments on this post

  1. Cog.Dog said on May 1, 2020 at 12:18 pm

    This is so impressive, Tom, both in concept and execution. I can just add a few more “Wows”.

    You’ve emigrated far from Non-Programmistan!

    • Tom Woodward said on May 10, 2020 at 9:12 am

      Always easier to make art look good, right? It is exposing me to a bunch of new problems and it is always nice to do stuff outside WP.