Skip to main content

add my chunky_pixels script

ID
58e4514
date
2023-08-19 07:45:25+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
7114174
message
add my chunky_pixels script
changed files
7 files, 106 additions

Changed files

images/README.md (4715) → images/README.md (5566)

diff --git a/images/README.md b/images/README.md
index c173fbd..d4daaee 100644
--- a/images/README.md
+++ b/images/README.md
@@ -6,6 +6,42 @@ These scripts are for working with images and other visual material.
 
 <dl>
   <dt>
+    <a href="https://github.com/alexwlchan/scripts/blob/main/images/chunky_pixels">
+      <code>chunky_pixels [PATH] [PIXEL_SIZE]</code>
+    </a>
+  </dt>
+  <dd>
+    redraw an image using “chunky” pixels – that is, replacing every NxN block of pixels with a single colour.
+    <p>
+      <table>
+        <tr>
+          <td>
+            <img src="examples/flowers.jpg">
+            original
+          </td>
+          <td>
+            <img src="examples/flowers_12.jpg">
+            N=12
+          </td>
+          <td>
+            <img src="examples/flowers_34.jpg">
+            N=34
+          </td>
+          <td>
+            <img src="examples/flowers_68.jpg">
+            N=68
+          </td>
+          <td>
+            <img src="examples/flowers_204.jpg">
+            N=204
+          </td>
+        </tr>
+      </table>
+    </p>
+  </dd>
+
+
+  <dt>
     <a href="https://github.com/alexwlchan/scripts/blob/main/images/copycrop">
       <code>copycrop</code>
     </a>

images/chunky_pixels (0) → images/chunky_pixels (2126)

diff --git a/images/chunky_pixels b/images/chunky_pixels
new file mode 100755
index 0000000..885dc5a
--- /dev/null
+++ b/images/chunky_pixels
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+"""
+Redraws the given image with 'chunky pixels' – every NxN chunk of pixels
+is replaced by a single colour.
+"""
+
+import colorsys
+import random
+import subprocess
+import sys
+import tempfile
+
+from PIL import Image, ImageDraw
+import tqdm
+
+
+def clamp(x, *, between):
+    lower, upper = between
+    return min([max([x, lower]), upper])
+
+
+if __name__ == "__main__":
+    try:
+        path = sys.argv[1]
+        pixel_size = int(sys.argv[2])
+    except (IndexError, ValueError):
+        sys.exit(f"Usage: {__file__} <PATH> <PIXEL_SIZE>")
+
+    im = Image.open(path)
+
+    assert im.width % pixel_size == 0
+    assert im.height % pixel_size == 0
+
+    all_colours = {}
+
+    with tempfile.TemporaryDirectory() as tmpdir:
+        for x_start in tqdm.tqdm(range(0, im.width, pixel_size)):
+            for y_start in range(0, im.height, pixel_size):
+                im_crop = im.crop(
+                    (x_start, y_start, x_start + pixel_size, y_start + pixel_size)
+                )
+                tmp_path = f"{tmpdir}/cropped_{x_start}_{y_start}.png"
+                im_crop.save(tmp_path)
+                colour = subprocess.check_output(
+                    ["dominant_colours", tmp_path, "--max-colours=1", "--no-palette"]
+                ).strip()
+                all_colours[(x_start, y_start)] = (
+                    int(colour[1:3], 16),
+                    int(colour[3:5], 16),
+                    int(colour[5:7], 16),
+                )
+
+    im = Image.new("RGB", im.size)
+    draw = ImageDraw.Draw(im)
+
+    for (x_start, y_start), (r, g, b) in all_colours.items():
+        h, l, s = colorsys.rgb_to_hls(r / 255, g / 255, b / 255)
+        l = clamp(l * random.uniform(0.9, 1.1), between=[0, 1])
+        s = clamp(s * random.uniform(0.9, 1.1), between=[0, 1])
+
+        r, g, b = colorsys.hls_to_rgb(h, l, s)
+        draw.rectangle(
+            [(x_start, y_start), (x_start + pixel_size), (y_start + pixel_size)],
+            fill=(int(r * 255), int(g * 255), int(b * 255)),
+        )
+
+    base, extension = path.rsplit(".", 1)
+
+    out_path = f"{base}_{pixel_size}.{extension}"
+    im.save(out_path)

images/examples/flowers.jpg (0) → images/examples/flowers.jpg (206100)

diff --git a/images/examples/flowers.jpg b/images/examples/flowers.jpg
new file mode 100644
index 0000000..590b5a3
Binary files /dev/null and b/images/examples/flowers.jpg differ

images/examples/flowers_12.jpg (0) → images/examples/flowers_12.jpg (44972)

diff --git a/images/examples/flowers_12.jpg b/images/examples/flowers_12.jpg
new file mode 100644
index 0000000..4f1d320
Binary files /dev/null and b/images/examples/flowers_12.jpg differ

images/examples/flowers_204.jpg (0) → images/examples/flowers_204.jpg (11333)

diff --git a/images/examples/flowers_204.jpg b/images/examples/flowers_204.jpg
new file mode 100644
index 0000000..50fda20
Binary files /dev/null and b/images/examples/flowers_204.jpg differ

images/examples/flowers_34.jpg (0) → images/examples/flowers_34.jpg (30640)

diff --git a/images/examples/flowers_34.jpg b/images/examples/flowers_34.jpg
new file mode 100644
index 0000000..920ad69
Binary files /dev/null and b/images/examples/flowers_34.jpg differ

images/examples/flowers_68.jpg (0) → images/examples/flowers_68.jpg (17109)

diff --git a/images/examples/flowers_68.jpg b/images/examples/flowers_68.jpg
new file mode 100644
index 0000000..ef0caaf
Binary files /dev/null and b/images/examples/flowers_68.jpg differ