项目作者: Pikecillo

项目描述 :
An interpreter of image transformations, inspired by *Beyond Photography: The Digital Darkroom*
高级语言: Python
项目地址: git://github.com/Pikecillo/digi-dark.git
创建时间: 2016-01-30T17:26:52Z
项目社区:https://github.com/Pikecillo/digi-dark

开源协议:GNU General Public License v3.0

下载


Darko

Darko is an interpreter of image transformations inspired by Popi (Portable Pico), described
in the classical book
Beyond Photography: The Digital Darkroom by
Gerard J. Holzmann.

Have fun distorting some pictures with one-liners, and feel free to contribute to this project.

Content

How to Run It

Darko is written in Python. To run it you need to install numpy and OpenCV. Last time it was tried with Python 3.7.6, but any Python 3 version should work.

  1. $ pip install SimpleParse
  2. $ pip install opencv-python

Run Demo

You can run a demo that generates all images shown in the Catalogue of Transformations
by doing:

  1. $ python darko.py

Run Darko Grammar Test

  1. python -m pytest tests

A Tutorial

Let’s apply some transformations on the following picture of scientist/physics-professor/safe-cracker/bongos-player/nobel-laureate extraordinaire Richard Feynman.

Feynman

Let’s load the darko interpreter and an image, and let’s operate on it using bilinear sampling

  1. import darko.interpreter
  2. # Create an interpreter
  3. darko_interpreter = darko.interpreter.Interpreter()
  4. # Load an image, and reads subpixels with bilinear interpolation
  5. darko_interpreter.load('feynman.jpg', sampling='bilinear')

Not let’s rotate the image by 45 degrees

  1. # Apply the transformation
  2. darko_interpreter.eval('new[x, y] = old[rect(r, a + rad(45))]')
  3. # Save result to a file
  4. darko_interpreter.save('feynman-rotated.jpg')

Feynman

Zooming-in on the image

  1. darko_interpreter.eval('new[x, y] = old[rect(r / 2, a)]')
  2. darko_interpreter.save('feynman-zoomed.jpg')

Feynman

Mirroring and translating the image

  1. darko_interpreter.eval('new[x, y] = old[abs(X / 2 - x), y]')
  2. darko_interpreter.save('feynman-mirrored.jpg')

Feynman

Thresholding the image in 2-pixel blocks

  1. transformation = """
  2. new[x, y] = gray(old[floor(x / 2) * 2, floor(y / 2) * 2]) > 150 ?
  3. rgb(255, 255, 255) : rgb(0, 0, 0)
  4. """
  5. darko_interpreter.eval(transformation)
  6. darko_interpreter.save('feynman-icon.jpg')

Feynman

A Warhol-like mosaic

  1. transformation = """
  2. new[x, y] =
  3. old[x % (X / 2) * 2, y % (Y / 2) * 2] *
  4. ((x < X / 2 ?
  5. (y < Y / 2 ? rgb(255, 0, 0) : rgb(0, 255, 0)) :
  6. (y < Y / 2 ? rgb(255, 255, 0) : rgb(0, 255, 255))) / Z)
  7. """
  8. darko_interpreter.eval(transformation)
  9. darko_interpreter.save('feynman-mosaic.jpg')

Feynman

A funky late 60s or early 70s look

  1. transformation = """
  2. new[x, y] =
  3. 0.33 * ((gray(Z - old[x - 25, y]) / Z) * rgb(0, 0, 255)) +
  4. 0.33 * ((gray(Z - old[x, y]) / Z) * rgb(0, 255, 0)) +
  5. 0.33 * ((gray(Z - old[x + 25, y]) / Z) * rgb(255, 0, 0))
  6. """
  7. darko_interpreter.eval(transformation)
  8. darko_interpreter.save('feynman-lsd.jpg')

Feynman

Keywords

You can use either polar coordinates or rectangular coordinates in your transformations. The origin of the
rectangular coordinates is at the top-left corner of the image, and the origin of the polar coordinates is
in the center of the image.

The following keywords can be used in transformations:

old: original image

new: transformed image

x: current pixel’s x in rectangular coordinates

y: current pixel’s y in rectangular coordinates

r: current pixel’s radius in polar coordinates

a: current pixel’s angle (in radians) in polar coordinates

cx: x of center of image rectangular coordinates

cy: y of center of image rectangular coordinates

R: Half-length of image diagonal

X: Width of image

Y: Height of image

Z: Depth of image (255)

Operators

The following operators can be used within expressions

Arithmetic: +, -, , /, *, %

Comparison: <, >, ==, !=, <=, >=

Logic: &&, ||

Trinary: cond ? texpr : fexpr

Functions

rect(r, a) -> (x, y): Polar to rectangular coordinates

polar(x, y) -> (r, a): Rectangular to polar coordinates

sin(x): Sine

cos(x): Cosine

sqrt(x): Square root

deg(x): Radians to degrees

rad(x): Degrees to radians

gray(p): Gray level of pixel

rgb(r, g, b): Color tuple

ceil(x): Ceiling

floor(x): Floor

A Catalogue of Transformations

Most of the following transformations were taken from
Beyond Photography: The Digital Darkroom.

Twist

  1. new[x, y] = old[rect(r, a - r / 50)]

Putin
Putin Twist

Bath

  1. new[x, y] = old[x + (x % 32) - 16, y]

Merkel
Merkel Bath

Wave

  1. new[x, y] = old[x + 10 * sin(rad(y) * 10), y]

Obama
Obama Wave

Funhouse

  1. new[x, y] = old[x + sin(rad(x)) * 150, y + sin(rad(y * 1.18)) * 89]

Jinping
Jinping Funhouse

Pond

  1. new[x, y] = old[x, y + 10 * sin(rad(y) * 10)]

Cameron
Cameron Pond

Negative

  1. new[x, y] = Z - old[x, y]

Cook
Cook Negative

Spiralbath

  1. new[x, y] = old[x, y + (deg(a) + r / 4) % 64 - 16]

Gates
Gates Spiralbath

Fisheye

  1. new[x, y] = old[rect(1.5 * r ** 2 / R, a)]

Bezos
Bezos

Caricature

  1. new[x, y] = old[rect(0.5 * sqrt(r * R), a)]

Page
Page Caricature

Curly

  1. new[x, y] = old[x + 10 * sin(rad(y) * 5), y + 10 * sin(rad(x) * 5)]

Brin
Brin Curly

Sink

  1. new[x, y] = old[rect(r + 10 * sin(rad(r) * 10), a - r / 50)]

Ma
Ma Sink

T2000

  1. new[x, y] = old[rect(1.5 * r ** 2 / R + 10 * sin(rad(r) * 10), a)]

Zuckerberg
Zuckerberg T2000

Pixel

  1. new[x, y] = old[floor(x / 10) * 10, floor(y / 10) * 10]

Musk
Musk

Bentley

  1. new[x, y - gray(old[x, y]) * 0.1] = old[x, y]

Nadella
Nadella Bentley