91 lines
1.7 KiB
Ruby
91 lines
1.7 KiB
Ruby
|
#!/usr/bin/env ruby
|
||
|
|
||
|
require 'rmagick'
|
||
|
|
||
|
# [ ] load the image
|
||
|
# [ ] map each pixel to a 12 bit color, with pixels less than 25% transparent as mask
|
||
|
# [ ] sort the color counts
|
||
|
# [ ] transparent pixels become the mask
|
||
|
# [ ] turn the big color counts into three bitplames worth of data
|
||
|
# [ ] turn the little color counts into up to 8 sprites worth of data strips & color changes
|
||
|
|
||
|
image = Magick::Image.read('topaz.png').first
|
||
|
|
||
|
rows = []
|
||
|
|
||
|
class MaskPixel
|
||
|
def initialize; end
|
||
|
|
||
|
def color? = false
|
||
|
end
|
||
|
|
||
|
class Color
|
||
|
attr_reader :red, :green, :blue
|
||
|
|
||
|
def initialize(red:, green:, blue:)
|
||
|
@red = red
|
||
|
@green = green
|
||
|
@blue = blue
|
||
|
end
|
||
|
|
||
|
def ==(other)
|
||
|
red == other.red && green == other.green && blue == other.blue
|
||
|
end
|
||
|
|
||
|
alias eql? ==
|
||
|
|
||
|
def hash
|
||
|
red * 256 + green * 16 + blue
|
||
|
end
|
||
|
end
|
||
|
|
||
|
class BitplanePixel
|
||
|
attr_reader :color
|
||
|
|
||
|
def initialize(color:)
|
||
|
@color = color
|
||
|
end
|
||
|
|
||
|
def color? = true
|
||
|
end
|
||
|
|
||
|
MAX_ALPHA = Magick::QuantumRange * 0.25
|
||
|
BIT_SHIFT = Math.log2(Magick::QuantumRange + 1) - 4
|
||
|
|
||
|
class PixelRow
|
||
|
def initialize
|
||
|
@row = []
|
||
|
end
|
||
|
|
||
|
def add(pixel:, x:)
|
||
|
@row[x] = pixel
|
||
|
end
|
||
|
|
||
|
def colors_with_usage
|
||
|
@row.find_all(&:color?).each_with_object({}) do |pixel, obj|
|
||
|
obj[pixel.color] ||= 0
|
||
|
obj[pixel.color] += 1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
image.each_pixel do |px, x, y|
|
||
|
rows[y] ||= PixelRow.new
|
||
|
|
||
|
pixel = if px.alpha < MAX_ALPHA
|
||
|
MaskPixel.new
|
||
|
else
|
||
|
BitplanePixel.new(
|
||
|
color: Color.new(
|
||
|
red: px.red >> BIT_SHIFT,
|
||
|
green: px.green >> BIT_SHIFT,
|
||
|
blue: px.blue >> BIT_SHIFT
|
||
|
)
|
||
|
)
|
||
|
end
|
||
|
|
||
|
rows[y].add(pixel:, x:)
|
||
|
end
|
||
|
|
||
|
pp rows[50].colors_with_usage
|