Skip to content

Instantly share code, notes, and snippets.

@sinefunc
Created June 29, 2011 00:44
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 sinefunc/3de1bcfae1622ff23835 to your computer and use it in GitHub Desktop.
Save sinefunc/3de1bcfae1622ff23835 to your computer and use it in GitHub Desktop.
require 'chunky_png'
module Pixelator
extend self
# Go go go!
def pixelize!(image)
for_each_block_of image do |x, y|
color = average_of all_colors_from block: [x, y], of: image
fill block: [x, y], with: color, of: image
end
image
end
# Iterates through each block of an image
def for_each_block_of(image, &blk)
(0..image.width/ten).each do |x|
(0..image.height/ten).each { |y| yield x, y }
end
end
# Fill a block with a color
def fill(options)
x, y = options[:block]
color = options[:with]
image = options[:of]
image.rect x*ten, y*ten, x*ten+ten, y*ten+ten, color, color if color
end
# Returns all colors in a given block range
def all_colors_from(options)
x, y = options[:block]
image = options[:of]
(0...ten * ten).map do |i|
_x, _y = (x * ten + i/ten), (y * ten + i%ten)
image[_x, _y] if image.include_xy?(_x, _y)
end.compact
end
# Adds a color to a hash-color
def add_color(hash, color)
channels.each { |chan|
hash[chan] ||= 0
hash[chan] += ChunkyPNG::Color.send(chan, color)
}
hash
end
# Divides a hash-color by a divisor
def divide_color(hash, divisor)
channels.each { |chan| hash[chan] /= divisor }
hash
end
# Averages a list of colors
def average_of(array)
if array.length > 0
h = array.inject({}) { |h, color| add_color(h, color) }
h = divide_color(h, array.length)
ChunkyPNG::Color.rgba(h[:r], h[:g], h[:b], h[:a])
end
end
# Color channels
def channels() [:r, :g, :b, :a]; end
# Block size
def ten() 10; end
end
image = Pixelator.pixelize! ChunkyPNG::Image.from_file('input.png')
image.save('output.png')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment