Fragments

The closest I'll ever come to blogging.


Fancies of an upside-down world


Then came The Wheel of Fortune at the very moment when we were expecting a more detailed description of the world of the Moon, which would allow us to indulge in the old fancies of an upside-down world, where the ass is king, man is four-legged, the young rule the old, sleepwalkers hold the rudder, citizens spin like squirrels in their cage's wheel, and there are as many other paradoxes as the imagination can disjoin and join.

-Italo Calvino, The Castle of Crossed Destines
translated by William Weaver

The Castle of Crossed Destinies - Wikipedia
en.wikipedia.org

The Castle of Crossed Destinies - Wikipedia

Untitled inbox collage #1

A week of internet content, newsletters, and notifications


From the past week of my inbox.

Digital collage of emails and other internet content

How I made this

First, I took screenshots of emails and newsletter content, as well as some other bits and bobs:

Then I wrote a python script to separate text from background in a particular image

import cv2
import numpy as np
import os
import argparse

def split_text_background(image_path, output_dir):
  os.makedirs(output_dir, exist_ok=True)

  image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)

  if image is None:
      print(f"Error: Could not open image at {image_path}")
      return

  if image.shape[2] == 3:  # If only BGR channels exist
      image = cv2.cvtColor(image, cv2.COLOR_BGR2BGRA)

  gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

  _, text_mask = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)

  text_only = np.zeros_like(image, dtype=np.uint8)
  text_only[:, :, 0:3] = image[:, :, 0:3]
  text_only[:, :, 3] = text_mask

  background_only = image.copy()
  background_only[:, :, 3] = cv2.bitwise_not(text_mask)

  base_name = os.path.splitext(os.path.basename(image_path))[0]
  background_output_path = os.path.join(output_dir, f"{base_name}_background.png") 
  text_output_path = os.path.join(output_dir, f"{base_name}_text.png") 

  cv2.imwrite(background_output_path, background_only)
  cv2.imwrite(text_output_path, text_only)

  print(f"✅ Background extracted and saved to: {background_output_path}")
  print(f"✅ Text extracted and saved to: {text_output_path}")

if __name__ == "__main__":
  parser = argparse.ArgumentParser(description="Split text and background from an image while preserving transparency.")
  parser.add_argument("image_path", help="Path to the input image")
  parser.add_argument("-o", "--output", default=".", help="Output directory (default: current directory)")

  args = parser.parse_args()

  split_text_background(args.image_path, args.output)

After creating these text masks the hard way, I got to work in Figma stitching it all together.