Skip to content

Instantly share code, notes, and snippets.

@1011X
Created October 11, 2018 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 1011X/911cfb6b329bb6d1e507bc610ac7af51 to your computer and use it in GitHub Desktop.
Save 1011X/911cfb6b329bb6d1e507bc610ac7af51 to your computer and use it in GitHub Desktop.
Encodes 3 strings into a colorful DataMatrix barcode
#!/usr/bin/env python3
# pip requirements:
# * Pillow 5.3.0
# * pylibdmtx 0.1.8
# license: BSD 0-clause
# This script encodes Data Matrix barcodes into each CMY color channel.
# No current software can decode this and is not a standard (as of yet).
# This is just a format I created for my own amusement.
import sys
from PIL import Image, ImageOps, ImageChops
from pylibdmtx.pylibdmtx import encode
if sys.argv[1] in ["-h", "--help"]:
cmd = sys.argv[0]
print("Uses:")
print("%s (-h | --help) - Display this message" % cmd)
print("%s NAME STRING STRING STRING - Encode 3 strings and name the file NAME" % cmd)
sys.exit(0)
filename = sys.argv[1]
encdata = [encode(str.encode(val)) for val in sys.argv[2:5]]
imgs = [Image.frombytes("RGB", (img.width, img.height), img.pixels) for img in encdata]
# make sure matrix codes are the same size
if not (imgs[0].height == imgs[1].height == imgs[2].height):
print("image sizes are not the same!")
print("sizes are, in order given: %d %d %d" % (imgs[0].height, imgs[1].height, imgs[2].height))
print("try changing or padding the messages to be the same size")
sys.exit(1)
dims = (imgs[0].width, imgs[0].height)
final_img = Image.new("RGB", dims)
# original images start out black on white.
for (i, img) in enumerate(imgs):
# turn them white on black
img = ImageOps.invert(img)
# replace white with the channel color
img = img.getchannel(['R', 'G', 'B'][i])
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
img = ImageOps.colorize(img, "black", colors[i])
# and add to blank image
final_img = ImageChops.add(final_img, img)
# invert it again
final_img = ImageOps.invert(final_img)
# we can't be clever by canceling out both inversions at once because
# overlapping CMY pixels added together saturate to white and erases the data.
# save, and we're done!
final_img.save(filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment