Skip to content

Instantly share code, notes, and snippets.

@tompng
Created May 28, 2024 16:13
Show Gist options
  • Save tompng/1ce139709119e54d1b0b6f023df25c89 to your computer and use it in GitHub Desktop.
Save tompng/1ce139709119e54d1b0b6f023df25c89 to your computer and use it in GitHub Desktop.
input: white-black map, output: rk2024-color map
require 'chunky_png'
img = ChunkyPNG::Image.from_file('okinawa_ishigaki_small.png')
alphas = img.height.times.map do |y|
img.width.times.map do |x|
((img[x,y] >> 8) & 0xff) / 255.0
end
end
lines = Hash.new(0)
borders = Hash.new(0)
add = ->(x, y, w = 2, target = lines) {
(x.round - w .. x.ceil + w).each do |ix|
(y.round - w .. y.ceil + w).each do |iy|
dist = Math.hypot(ix - x, iy - y)
next if dist > w
target[[iy, ix]] = [target[[iy, ix]], [w - dist, 1].min].max
end
end
}
(img.width-1).times do |x|
(img.height-1).times do |y|
a = (alphas[y][x]-0.5).abs
if alphas[y][x]>0.5 != alphas[y][x+1]>0.5
b = (alphas[y][x+1]-0.5).abs
add[x + a / (a + b) , y]
end
if alphas[y][x]>0.5 != alphas[y+1][x]>0.5
b = (alphas[y+1][x]-0.5).abs
add[x, y + a / (a + b)]
end
end
end
img.width.times do |x|
add[x, 400+Math.sin(x/100.0+50)*40, 8, borders]
end
def mix(base, color, alpha)
base.zip(color).map { |bg, fg| (fg * alpha + bg * (1 - alpha)).round }
end
p borders.size
img.height.times do |y|
img.width.times do |x|
fg = [128, 241, 66]
bg = [255, 235, 0]
col = alphas[y][x] > 0.5 ? fg : bg
col = mix(col, [0, 0, 0], lines[[y,x]])
r, g, b = mix(col, [255, 255, 255], borders[[y,x]])
img[x,y] = (r<<24)|(g<<16)|(b<<8)|0xff
end
end
img.save('okinawa_ishigaki_small_colorized.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment