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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/Rakefile +2 -0
- data/bin/flambient +17 -0
- data/flambient.gemspec +20 -0
- data/lib/flambient.rb +1 -0
- data/lib/flambient/processor.rb +128 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/bin/flambient
ADDED
@@ -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])
|
data/flambient.gemspec
ADDED
@@ -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
|
data/lib/flambient.rb
ADDED
@@ -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: []
|