Skip to content

Instantly share code, notes, and snippets.

@wgmyers
Created March 5, 2023 03:47
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 wgmyers/1fb9e7e1e3e01605d816884facf44042 to your computer and use it in GitHub Desktop.
Save wgmyers/1fb9e7e1e3e01605d816884facf44042 to your computer and use it in GitHub Desktop.
Extract and sort colour values from a heatmap of PIN usage
#!/usr/bin/env ruby
# frozen_string_literal: true
# extract.rb
# See https://archive.is/2Qtyr
# Extract the colour values from a 700x700 heatmap png
# representing a 100x100 grid of all possible 4 digit
# PIN numbers 'abcd' with 'ab' on the X axis and 'cd'
# on the Y axis.
DATA = {}
# get_hex
# Convert our srgb(r,g,b) data to hex
# Annoyingly, we are getting names back as well, as ImageMagick sees fit.
def get_hex(srgb)
if srgb !~ /^srgb/
case srgb
when 'red'
srgb = "srgb(255,0,0)\n"
when 'gold'
srgb = "srgb(255,215,0)\n"
when 'OrangeRed'
srgb = "srgb(255,69,0)\n"
when 'black'
srgb = "srgb(0,0,0)\n"
when 'orange'
srgb = "srgb(255,165,0)\n"
when 'DarkOrange'
srgb = "srgb(255,140,0)\n"
when 'white'
srgb = "srgb(255,255,255)\n"
when 'yellow'
srgb = "srgb(255,255,0)\n"
else
puts "Look up #{srgb} and add it in."
exit
end
end
str = srgb[5..-2]
(r, g, b) = str.split(',')
r = r.to_i.to_s(16).rjust(2, '0')
g = g.to_i.to_s(16).rjust(2, '0')
b = b.to_i.to_s(16).rjust(2, '0')
"#{r}#{g}#{b}"
end
# get_colour
# Use ImageMagick to extract the pixel colour from our target image at the given co-ordinates
def get_colour(px, py)
res = `convert pin-heatmap.png -format "%[pixel:u.p{#{px},#{py}]\n" info:`
res.chop # lose newline at end
end
# get_pixel
# Convert x and y to the correct pixel in the image
# Image has x axis l->r, and y axis bottom->top
# So 0,0 (PIN 0000) should return something like 0, 700 but
# 99,99 (PIN 9999) should return something like 700,0
def get_pixel(x, y)
rx = (x * 7) + 3
ry = (700 - (y * 7)) - 3
[rx, ry]
end
# get_pin
# Convert x and y to the relevant pin
def get_pin(x, y)
result = ''
result += '0' if x < 10
result += x.to_s
result += '0' if y < 10
result += y.to_s
result
end
(0..99).each do |ab|
(0..99).each do |cd|
pin = get_pin(ab, cd)
pix = get_pixel(ab, cd)
col = get_colour(pix[0], pix[1])
hex = get_hex(col)
DATA[pin] = hex
end
end
# This should not work, but seems to
pp DATA.sort_by { |_k, v| v }.reverse
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment