flambient 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d0a17dbd56e0fb11949760f71e4bb83b54a2ba1
4
+ data.tar.gz: 3bf2040f2239df137f001fc182100717441ffdad
5
+ SHA512:
6
+ metadata.gz: 93b5f7c375ccf0fe3b03ab67321ecd7badb92937a037a9a39059e61c0bf6f4b32da0ef184df57498dc05a1f8c64756cafe97bfe42e1e7912cb8e4e815541bc82
7
+ data.tar.gz: 38a08294110fd9f7b3eb5f1f818bb56e59b200e3e2bedb8c3baa61b0141047ac59a58e5841d83507a0064306ff59175ef40884ef8022399fae159784832b5e72
@@ -0,0 +1,3 @@
1
+ *.png
2
+ Gemfile.lock
3
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'flambient'
4
+
5
+ if ARGV[0].nil?
6
+ raise "No input path supplied"
7
+ end
8
+
9
+ if ARGV[1].nil?
10
+ raise "No output path supplied"
11
+ end
12
+
13
+ image = ChunkyPNG::Image.from_file(ARGV[0])
14
+ processor = Flambient::Processor.new(image, 64)
15
+
16
+ new_image = processor.process
17
+ new_image.save(ARGV[1])
@@ -0,0 +1,20 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "flambient"
5
+ s.version = "0.0.1"
6
+ s.authors = ["Tom Taylor"]
7
+ s.email = ["tom@tomtaylor.co.uk"]
8
+ s.homepage = "https://github.com/tomtaylor/flambient"
9
+ s.summary = "Triangular pixel effects on PNGs"
10
+
11
+ s.files = `git ls-files`.split($\)
12
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
13
+ s.require_paths = ["lib"]
14
+ s.executables = ["flambient"]
15
+
16
+ s.add_dependency "chunky_png", '~> 1.2.9'
17
+ s.add_dependency "oily_png", '~> 1.1.0'
18
+
19
+ s.add_development_dependency "rake"
20
+ end
@@ -0,0 +1 @@
1
+ require 'flambient/processor'
@@ -0,0 +1,128 @@
1
+ require 'chunky_png'
2
+ require 'oily_png'
3
+
4
+ module Flambient
5
+ class Processor
6
+
7
+ attr_reader :tile_size, :image
8
+
9
+ def initialize(image, tile_size = 32)
10
+ @image = image
11
+ @tile_size = tile_size
12
+ end
13
+
14
+ def process
15
+ # Round the size of the image down to the nearest tile
16
+ width = (image.width / tile_size) * tile_size
17
+ height = (image.height / tile_size) * tile_size
18
+ new_image = ChunkyPNG::Canvas.new(width, height, ChunkyPNG::Color::TRANSPARENT)
19
+
20
+ (0...width).step(tile_size) do |x|
21
+ (0...height).step(tile_size) do |y|
22
+ process_tile(new_image, x, y)
23
+ end
24
+ end
25
+
26
+ new_image
27
+ end
28
+
29
+ private
30
+
31
+ def process_tile(new_image, x, y)
32
+ top, left, bottom, right = quad_colours(x, y)
33
+
34
+ p_top_left = [x, y]
35
+ p_top_right = [x + tile_size, y]
36
+ p_bottom_left = [x, y + tile_size]
37
+ p_bottom_right = [x + tile_size, y + tile_size]
38
+
39
+ # Change the angle of the triangle depending on the closest matching
40
+ # colour.
41
+ if color_distance(top, left) > color_distance(top, right)
42
+ c1 = average_color([top, left])
43
+ c2 = average_color([bottom, right])
44
+
45
+ new_image.polygon([p_top_left, p_top_right, p_bottom_left], c1, c1)
46
+ new_image.polygon([p_top_right, p_bottom_left, p_bottom_right], c2, c2)
47
+ else
48
+ c1 = average_color([top, right])
49
+ c2 = average_color([bottom, left])
50
+
51
+ new_image.polygon([p_top_left, p_top_right, p_bottom_right], c1, c1)
52
+ new_image.polygon([p_top_left, p_bottom_left, p_bottom_right], c2, c2)
53
+ end
54
+ end
55
+
56
+ # Returns the average colours for different portions of the tile.
57
+ def quad_colours(tile_x, tile_y)
58
+ [:top, :left, :bottom, :right].map do |side|
59
+ average_color(triangle_pixels(tile_x, tile_y, side))
60
+ end
61
+ end
62
+
63
+ # This is meant to return the pixels for a triangle in a tile, but instead
64
+ # does a simple rectangle, because I couldn't be bothered to think about
65
+ # the maths.
66
+ def triangle_pixels(tile_x, tile_y, side)
67
+ quad_size = tile_size / 2
68
+
69
+ case side
70
+ when :top
71
+ p1 = [tile_x, tile_y]
72
+ p2 = [tile_x + tile_size, tile_y + quad_size]
73
+ when :left
74
+ p1 = [tile_x, tile_y]
75
+ p2 = [tile_x + quad_size, tile_y + tile_size]
76
+ when :bottom
77
+ p1 = [tile_x, tile_y + quad_size]
78
+ p2 = [tile_x + tile_size, tile_y + tile_size]
79
+ when :right
80
+ p1 = [tile_x + quad_size, tile_y]
81
+ p2 = [tile_x + tile_size, tile_y + tile_size]
82
+ end
83
+
84
+ p1 = ChunkyPNG.Point(p1)
85
+ p2 = ChunkyPNG.Point(p2)
86
+
87
+ [].tap do |pixels|
88
+ (p1.x...p2.x).each do |x|
89
+ (p1.y...p2.y).each do |y|
90
+ pixels << image.get_pixel(x, y)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Calculates the average colour of an array of pixels
97
+ def average_color(pixels)
98
+ r_avg = 0; g_avg = 0; b_avg = 0
99
+ count = pixels.length
100
+
101
+ pixels.each do |pixel|
102
+ r, g, b = ChunkyPNG::Color.to_truecolor_bytes(pixel)
103
+ r_avg += r
104
+ g_avg += g
105
+ b_avg += b
106
+ end
107
+
108
+ r_avg = r_avg / count
109
+ g_avg = g_avg / count
110
+ b_avg = b_avg / count
111
+
112
+ ChunkyPNG::Color.rgb(r_avg, g_avg, b_avg)
113
+ end
114
+
115
+ # See http://en.wikipedia.org/wiki/Hue#Computing_hue_from_RGB
116
+ def color_hue(pixel)
117
+ r, g, b = ChunkyPNG::Color.to_truecolor_bytes(pixel)
118
+ return 0 if r == b and b == g
119
+ ((180 / Math::PI * Math.atan2((2 * r) - g - b, Math.sqrt(3) * (g - b))) - 90) % 360
120
+ end
121
+
122
+ # The modular distance, as the hue is circular
123
+ def color_distance(pixel, poxel)
124
+ hue_pixel, hue_poxel = color_hue(pixel), color_hue(poxel)
125
+ [(hue_pixel - hue_poxel) % 360, (hue_poxel - hue_pixel) % 360].min
126
+ end
127
+ end
128
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flambient
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tom Taylor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: chunky_png
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.9
27
+ - !ruby/object:Gem::Dependency
28
+ name: oily_png
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - tom@tomtaylor.co.uk
58
+ executables:
59
+ - flambient
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - Rakefile
66
+ - bin/flambient
67
+ - flambient.gemspec
68
+ - lib/flambient.rb
69
+ - lib/flambient/processor.rb
70
+ homepage: https://github.com/tomtaylor/flambient
71
+ licenses: []
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.2.0
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Triangular pixel effects on PNGs
93
+ test_files: []