How to Build a Computer Using Photoshop Actions

A Turing machine implemented in Adobe Photoshop
  Ava Pun  •    Oct 14, 2023  •   10 min   computer-science  turing-machine  photoshop 

Last time, I showed you how to implement Conway’s Game of Life in Clip Studio Paint. In this second instalment of Using Digital Art Programs for Unintended Purposes, I present you with a working computer programmed using Adobe Photoshop Actions.

A Turing machine implemented in Adobe Photoshop.

To be specific, this computer is a Turing machine—an abstract machine capable of running any computer algorithm. I’ll show you how to create this machine by using layer blend modes and the Invert command to perform logical computations. Let’s begin!

Performing boolean operations with layer blend modes

Before creating a computer, we must start with some basic building blocks—the boolean operations AND, OR, and NOT. As a refresher:

  • AND returns 1 if both of its inputs are 1.
  • OR returns 1 if at least one of its inputs is 1.
  • NOT negates its input—1 becomes 0 and vice versa.

To implement boolean operations in an image manipulation program like Photoshop, we will represent 0 and 1 by a black and a white square, respectively.

black-white-squares.jpg

Applying the NOT operation to these squares is simple: just use the Invert command by clicking Image > Adjustments > Invert (or pressing Ctrl-I). This command inverts the colours of the active layer, turning white into black and vice versa.

The Invert command inverts the colours of the layer.

What about AND and OR? To implement these, we’ll use layer blend modes. As I briefly discussed in the Game of Life post, layers are components of a Photoshop file that can be arranged and adjusted independently. Each pixel in a layer has three colour channels—red, green, and blue—which range from 0 to 1. Black is represented by three 0’s, while white is represented by three 1’s. Layer blend modes are used to blend two layers by combining the values of their colour channels.

We’ll focus on two layer blend modes today:

  • Multiply, which multiplies the pixel values of the two layers. I.e., if the two values are x and y, the final value is xy.
  • Screen, which inverts the two values, multiplies them together, and inverts the result. I.e., if the two pixel values are x and y, the final value is 1–(1–x)(1–y).

Both blend modes apply to the three colour channels separately.

The effect of the Multiply and Screen blend modes.

Notice that the result of Multiply is white if both input layers are white. On the other hand, the result of Screen is white if at least one layer is white. In other words, Multiply and Screen act like the AND and OR operators! So, if we wanted to AND two inputs, we would:

  1. Copy those inputs to new layers, and stack the layers on top of each other.
  2. Set the top layer’s blend mode to Multiply.
  3. Merge the two layers together (by clicking Layer > Merge Layers or pressing Ctrl-E).
Using a Multiply layer to perform the AND operation.

All that copying and merging could get tedious. Fortunately, Photoshop allows us to record the process and save it as an Action, which can be accessed via the Window > Actions menu. This enables us to calculate the output with just one click.

Performing the same AND operation with a single click via an Action.

Now, we can run arbitrary boolean computations in Photoshop with ease! And that’s all we need to implement more complex machines.

Implementing a multiplexor

Let’s start with something simple: a 2-input multiplexor, which outputs one of its two inputs depending on the value of a given selector. In our Photoshop file, we’ll create two input squares, IN0 and IN1; an output square, OUT; and a selector square, S.

A 2-input, 1-selector multiplexor.
A 2-input, 1-selector multiplexor.

We want OUT to reflect IN0 if S is black and IN1 if S is white. In other words, OUT should be white if and only if S is black and IN0 is white OR S and IN1 are both white. To put it in equation form:

OUT = ((NOT S) AND IN0) OR (S AND IN1)

We run this computation in Photoshop by performing the following steps:

  1. Copy S to OUT, and Invert the copied S.
  2. Copy IN0 to OUT, set the copied IN0 to Multiply, and merge it with the copied S to create (NOT S) AND IN0.
  3. Copy S to OUT again.
  4. Copy IN1 to OUT, set the copied IN1 to Multiply, and merge it with the copied S to create S AND IN1.
  5. Set S AND IN1 to Screen, and merge it with (NOT S) AND IN0.

Whew! That’s a lot of copying and moving, but we can save it all into a single Photoshop Action.

Running a 2-input multiplexor with a Photoshop Action. If the selector S is black, the multiplexor copies IN0 to OUT; otherwise, it copies IN1 to OUT.

Now we have a 2-input multiplexor! Note that this multiplexor functions correctly even if the input colours are not limited to black or white. We can also extend it to take four inputs and two selectors—implementation is left as an exercise to the reader.

A 4-input multiplexor, implemented similarly to the 2-input one.
A 4-input multiplexor, implemented similarly to the 2-input one.

Using Difference and Threshold to create an equality comparator

Let’s try building something else: an equality comparator, which outputs white if the inputs are equal and black otherwise. In equation form:

OUT = ((NOT IN0) AND (NOT IN1)) OR (IN0 AND IN1)

We could implement this in a similar way as the multiplexor. But what if we wanted to support coloured inputs, not just black and white? A straightforward implementation wouldn’t work in this case.

The Difference blend mode comes to the rescue! As the name says, this mode computes the colour difference between two layers, resulting in black if the two colours are the same.

The effect of the Difference blend mode.

If the two colours are different, the result will be some colour other than black. We can force this colour to be white by applying the Threshold adjustment, found in Image > Adjustments, with a Threshold Level of 1.

A Level 1 Threshold adjustment forces all colours, except black, to be white.

If we apply the Difference blend mode to the inputs and then apply a Threshold, the output will be black if the inputs are identical and white otherwise. Invert the output, and we have an equality comparator! Both equality comparators and multiplexors will be used to build our Photoshop Turing Machine.

An equality comparator. It sets OUT to white if IN0 and IN1 are equal; otherwise, it sets OUT to black.

How to build a Turing machine

We’re finally ready to build a Turing machine. If you’re unfamiliar with how Turing machines work, don’t worry; I’ll explain it as we go.

A Turing machine contains an infinitely long tape stretching in both directions. The tape is divided into cells, and a head points to the cell that is currently “active.” Each cell is either blank or contains a symbol, typically the binary digit 0 or 1. On our Photoshop Turing Machine tape, we will interpret a black cell as a blank, a grey cell as the symbol 0, and a white cell as the symbol 1. (Note that this differs from our previous definition of pixel values, where a black cell represented 0.)

A Photoshop Turing Machine tape. This tape contains the binary string 1011, which represents the decimal number 11. The head points to the last 1 in the string.
A Photoshop Turing Machine tape. This tape contains the binary string 1011, which represents the decimal number 11. The head points to the last 1 in the string.

Along with the tape, a Turing machine has a current state (which we also represent with a colour). To program a Turing machine, we begin with providing a starting state and a set of rules, one for every combination of state and symbol. Each rule specifies a symbol, direction (left, right, or stay), and next state. At each step, the machine decides which rule to follow based on the current state and symbol in the active cell. Then, based on the rule, the machine performs three actions:

  1. Write the specified symbol in the active cell.
  2. Move the tape in the specified direction.
  3. Set the current state to the next one specified.

This process continues until the machine hits a “halt” state (which we represent with black). Amazingly, any computer algorithm can be implemented with these simple rules!

In our Photoshop Turing Machine, we present rules in a table. Each column in the table has seven coloured cells, which specify the following:

  • The current STATE and active SYMBOL required for the machine to follow this rule.
  • The symbol that the machine should WRITE to the tape.
  • The direction in which the tape should move, indicated by colouring one cell white among the cells LEFT, RIGHT, and STAY.
  • The NEXT state.

We also create a separate CURRENT column, used to hold the active rule.

The rule table and CURRENT column for our Photoshop Turing Machine. This particular set of rules adds 1 to the number on the tape. The currently active rule is for the state “red” and symbol “grey.”
The rule table and CURRENT column for our Photoshop Turing Machine. This particular set of rules adds 1 to the number on the tape. The currently active rule is for the state “red” and symbol “grey.”

Combine the rule table with the tape, and we have a full Turing machine!

The finished Turing machine, ready to run.
The finished Turing machine, ready to run.

Running the Turing machine

To run our Turing machine machine, we first specify the starting state by filling in the NEXT cell of the CURRENT column. Then, for each machine step, we do the following:

  1. Use an equality comparator to determine which rule’s STATE and SYMBOL equal the current ones.
  2. Copy the correct rule into the CURRENT column, using the comparator’s results as the selection input to a multiplexor.
  3. Copy the current WRITE symbol into the active tape cell.
  4. Move the tape according to the current LEFT, RIGHT, and STAY values. This can be done by creating a left-shifted, a right-shifted, and a stationary copy of the tape, then choosing which copy to keep via a multiplexor that takes LEFT, RIGHT, and STAY as its selection input.
  5. Use the state in the NEXT cell of the CURRENT column for the next step.

We package these moves into a single “Step Turing Machine” Action. Unfortunately, I haven’t figured out how to make the machine halt automatically, so we’ll just have to keep clicking “Step Turing Machine” until we see the halt state. But other than that, we now have a working Turing machine! A link to all the Photoshop files and Actions is here if you want to try them out yourself (they’ve been tested with Photoshop 2022).

Using the Photoshop Turing Machine to add 1 to its input. We write the number 11 (binary digits 1011) on the tape and set the starting state to red. After several “Step Turing Machine” actions, the machine outputs 12 (1100).

Final thoughts (+ bonus Photoshop Machine: an adder)

While experimenting with Photoshop Actions, I also created this adder, which takes two 3-bit binary inputs and outputs their sum. On the right, it features a seven-segment display that updates in sync with the inputs and output.

Next time you need a calculator, just open Photoshop.

The adder didn’t quite fit in with the rest of the post, but I thought it was worth mentioning anyway. It’s included in the Photoshop files if you want to take a look.

It took 34 Actions containing a total of 257 individual steps for me to implement the adder, while the Turing machine took 19 Actions and 149 individual steps. In both cases, I avoided repeating steps by calling Actions from within other Actions. When possible, I also placed multiple squares on the same layer in such a way that boolean operations could be computed “in parallel.”

I hope you’ve enjoyed exploring the interesting possibilities of Photoshop Actions with me! Perhaps you even have your own fun ideas for this unusual programming method. Thanks for reading, and see you next time!


See also: