pixelart 0.1.6 → 0.2.2
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 +4 -4
- data/Manifest.txt +3 -0
- data/lib/pixelart/base.rb +9 -0
- data/lib/pixelart/color.rb +0 -1
- data/lib/pixelart/composite.rb +77 -0
- data/lib/pixelart/image.rb +37 -8
- data/lib/pixelart/led.rb +37 -0
- data/lib/pixelart/misc.rb +29 -0
- data/lib/pixelart/pixelator.rb +165 -0
- data/lib/pixelart/version.rb +2 -2
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c2b93e1779a1c06ff0b13dbfcae471648cd2f2dc153b17da3fd864615f6f6c1
|
4
|
+
data.tar.gz: cef870177214b37eb902a99a41410dc8c080b613fed7c48cccd801290392fd28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ac5ad9fd3e16d9d490d7c43c38fa2b95ee6318a7c0f319e142fc59084ab70315ebb3d0e800d4536a098214768cab3adae99b1ec2c482ce93a4ab1e902d36cc5
|
7
|
+
data.tar.gz: 67e9e1214ae9f614a2694d30a9b63ce5aa2c83dad17a98dac141913b86cb4375ea22fc0630e2e3160f6b768b4b79ab2236555d0467471fd6a127f477ca48f6db
|
data/Manifest.txt
CHANGED
@@ -5,8 +5,11 @@ Rakefile
|
|
5
5
|
lib/pixelart.rb
|
6
6
|
lib/pixelart/base.rb
|
7
7
|
lib/pixelart/color.rb
|
8
|
+
lib/pixelart/composite.rb
|
8
9
|
lib/pixelart/gradient.rb
|
9
10
|
lib/pixelart/image.rb
|
11
|
+
lib/pixelart/led.rb
|
10
12
|
lib/pixelart/misc.rb
|
11
13
|
lib/pixelart/palette.rb
|
14
|
+
lib/pixelart/pixelator.rb
|
12
15
|
lib/pixelart/version.rb
|
data/lib/pixelart/base.rb
CHANGED
@@ -14,9 +14,16 @@ require 'pixelart/color'
|
|
14
14
|
require 'pixelart/gradient'
|
15
15
|
require 'pixelart/palette'
|
16
16
|
require 'pixelart/image'
|
17
|
+
require 'pixelart/composite'
|
18
|
+
|
19
|
+
require 'pixelart/pixelator'
|
17
20
|
|
18
21
|
require 'pixelart/misc' ## misc helpers
|
19
22
|
|
23
|
+
require 'pixelart/led' ## (special) effects / filters
|
24
|
+
|
25
|
+
|
26
|
+
|
20
27
|
|
21
28
|
##########
|
22
29
|
# add some spelling convenience variants
|
@@ -27,6 +34,8 @@ module Pixelart
|
|
27
34
|
|
28
35
|
Palette256Image = Palette8BitImage = Palette8bitImage =
|
29
36
|
ImagePalette256 = ImagePalette8Bit = ImagePalette8bit
|
37
|
+
|
38
|
+
CompositeImage = ImageComposite
|
30
39
|
end
|
31
40
|
|
32
41
|
|
data/lib/pixelart/color.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
module Pixelart
|
2
|
+
|
3
|
+
class ImageComposite < Image # check: (re)name to Collage, Sheet, Sprites, or such?
|
4
|
+
|
5
|
+
## default tile width / height in pixel -- check: (re)name to sprite or such? why? why not?
|
6
|
+
TILE_WIDTH = 24
|
7
|
+
TILE_HEIGHT = 24
|
8
|
+
|
9
|
+
|
10
|
+
def initialize( *args, **kwargs )
|
11
|
+
@tile_width = kwargs[:width] || kwargs[:tile_width] || TILE_WIDTH
|
12
|
+
@tile_height = kwargs[:height] || kwargs[:tile_height] || TILE_HEIGHT
|
13
|
+
|
14
|
+
## todo/fix: check type - args[0] is Image!!!
|
15
|
+
if args.size == 1 ## assume "copy" c'tor with passed in image
|
16
|
+
img = args[0] ## pass image through as-is
|
17
|
+
|
18
|
+
@tile_cols = img.width / @tile_width ## e.g. 2400/24 = 100
|
19
|
+
@tile_rows = img.height / @tile_height ## e.g. 2400/24 = 100
|
20
|
+
@tile_count = @tile_cols * @tile_rows ## ## 10000 = 100x100 (2400x2400 pixel)
|
21
|
+
elsif args.size == 2 || args.size == 0 ## cols, rows
|
22
|
+
## todo/fix: check type - args[0] & args[1] is Integer!!!!!
|
23
|
+
## todo/check - find a better name for cols/rows - why? why not?
|
24
|
+
@tile_cols = args[0] || 3
|
25
|
+
@tile_rows = args[1] || 3
|
26
|
+
@tile_count = 0 # (track) current index (of added images)
|
27
|
+
|
28
|
+
img = ChunkyPNG::Image.new( @tile_cols * @tile_width,
|
29
|
+
@tile_rows * @tile_height )
|
30
|
+
else
|
31
|
+
raise ArgumentError, "cols, rows or image arguments expected; got: #{args.inspect}"
|
32
|
+
end
|
33
|
+
|
34
|
+
puts " #{img.height}x#{img.width} (height x width)"
|
35
|
+
|
36
|
+
super( nil, nil, img )
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def count() @tile_count; end
|
41
|
+
alias_method :size, :count ## add size alias (confusing if starting with 0?) - why? why not?
|
42
|
+
|
43
|
+
#####
|
44
|
+
# set / add tile
|
45
|
+
|
46
|
+
def add( image )
|
47
|
+
y, x = @tile_count.divmod( @tile_cols )
|
48
|
+
|
49
|
+
puts " [#{@tile_count}] @ (#{x}/#{y}) #{image.width}x#{image.height} (height x width)"
|
50
|
+
|
51
|
+
## note: image.image - "unwrap" the "raw" ChunkyPNG::Image
|
52
|
+
@img.compose!( image.image, x*@tile_width, y*@tile_height )
|
53
|
+
@tile_count += 1
|
54
|
+
end
|
55
|
+
alias_method :<<, :add
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
######
|
60
|
+
# get tile
|
61
|
+
|
62
|
+
def tile( index )
|
63
|
+
y, x = index.divmod( @tile_cols )
|
64
|
+
img = @img.crop( x*@tile_width, y*@tile_height, @tile_width, @tile_height )
|
65
|
+
Image.new( img.width, img.height, img ) ## wrap in pixelart image
|
66
|
+
end
|
67
|
+
|
68
|
+
def []( *args ) ## overload - why? why not?
|
69
|
+
if args.size == 1
|
70
|
+
index = args[0]
|
71
|
+
tile( index )
|
72
|
+
else
|
73
|
+
super ## e.g [x,y] --- get pixel
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end # class ImageComposite
|
77
|
+
end # module Pixelart
|
data/lib/pixelart/image.rb
CHANGED
@@ -9,7 +9,14 @@ def self.read( path ) ## convenience helper
|
|
9
9
|
end
|
10
10
|
|
11
11
|
|
12
|
-
|
12
|
+
|
13
|
+
CHARS = '.@xo^~%*+=:' ## todo/check: rename to default chars or such? why? why not?
|
14
|
+
|
15
|
+
## todo/check: support default chars encoding auto-of-the-box always
|
16
|
+
## or require user-defined chars to be passed in - why? why not?
|
17
|
+
def self.parse( pixels, colors:, chars: CHARS )
|
18
|
+
has_keys = colors.is_a?(Hash) ## check if passed-in user-defined keys (via hash table)?
|
19
|
+
|
13
20
|
colors = parse_colors( colors )
|
14
21
|
pixels = parse_pixels( pixels )
|
15
22
|
|
@@ -20,7 +27,19 @@ def self.parse( pixels, colors: )
|
|
20
27
|
|
21
28
|
pixels.each_with_index do |row,y|
|
22
29
|
row.each_with_index do |color,x|
|
23
|
-
pixel =
|
30
|
+
pixel = if has_keys ## if passed-in user-defined keys check only the user-defined keys
|
31
|
+
colors[color]
|
32
|
+
else
|
33
|
+
## try map ascii art char (.@xo etc.) to color index (0,1,2)
|
34
|
+
## if no match found - fallback on assuming draw by number (0 1 2 etc.) encoding
|
35
|
+
pos = chars.index( color )
|
36
|
+
if pos
|
37
|
+
colors[ pos.to_s ]
|
38
|
+
else ## assume nil (not found)
|
39
|
+
colors[ color ]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
24
43
|
img[x,y] = pixel
|
25
44
|
end # each row
|
26
45
|
end # each data
|
@@ -31,6 +50,9 @@ end
|
|
31
50
|
|
32
51
|
|
33
52
|
def initialize( width, height, initial=Color::TRANSPARENT )
|
53
|
+
### todo/fix:
|
54
|
+
## change params to *args only - why? why not?
|
55
|
+
## make width/height optional if image passed in?
|
34
56
|
|
35
57
|
if initial.is_a?( ChunkyPNG::Image )
|
36
58
|
@img = initial
|
@@ -73,6 +95,13 @@ def grayscale
|
|
73
95
|
Image.new( img.width, img.height, img )
|
74
96
|
end
|
75
97
|
|
98
|
+
def mirror
|
99
|
+
img = @img.mirror
|
100
|
+
Image.new( img.width, img.height, img )
|
101
|
+
end
|
102
|
+
alias_method :flip_vertically, :mirror
|
103
|
+
|
104
|
+
|
76
105
|
## add replace_colors alias too? - why? why not?
|
77
106
|
def change_colors( color_map )
|
78
107
|
color_map = _parse_color_map( color_map )
|
@@ -170,6 +199,9 @@ def []=( x, y, value ) @img[x,y]=value; end
|
|
170
199
|
|
171
200
|
def pixels() @img.pixels; end
|
172
201
|
|
202
|
+
### todo/check: add colors() e.g. @img.pixels.uniq - why? why not?
|
203
|
+
|
204
|
+
|
173
205
|
## return image ref - use a different name - why? why not?
|
174
206
|
## change to to_image - why? why not?
|
175
207
|
def image() @img; end
|
@@ -183,10 +215,7 @@ def self.parse_pixels( pixels )
|
|
183
215
|
data = []
|
184
216
|
pixels.each_line do |line|
|
185
217
|
line = line.strip
|
186
|
-
if line.empty?
|
187
|
-
puts "!! WARN: skipping empty line in pixel art source"
|
188
|
-
next
|
189
|
-
end
|
218
|
+
next if line.start_with?( '#' ) || line.empty? ## note: allow comments and empty lines
|
190
219
|
|
191
220
|
## note: allow multiple spaces or tabs to separate pixel codes
|
192
221
|
## e.g. o o o o o o o o o o o o dg lg w w lg w lg lg dg dg w w lg dg o o o o o o o o o o o
|
@@ -197,12 +226,13 @@ def self.parse_pixels( pixels )
|
|
197
226
|
end
|
198
227
|
|
199
228
|
|
229
|
+
|
200
230
|
def self.parse_colors( colors )
|
201
231
|
if colors.is_a?( Array ) ## convenience shortcut
|
202
232
|
## note: always auto-add color 0 as pre-defined transparent - why? why not?
|
203
233
|
h = { '0' => Color::TRANSPARENT }
|
204
234
|
colors.each_with_index do |color, i|
|
205
|
-
|
235
|
+
h[ (i+1).to_s ] = Color.parse( color )
|
206
236
|
end
|
207
237
|
h
|
208
238
|
else ## assume hash table with color map
|
@@ -215,7 +245,6 @@ def self.parse_colors( colors )
|
|
215
245
|
end
|
216
246
|
|
217
247
|
|
218
|
-
|
219
248
|
end # class Image
|
220
249
|
end # module Pixelart
|
221
250
|
|
data/lib/pixelart/led.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Pixelart
|
2
|
+
|
3
|
+
|
4
|
+
class Image
|
5
|
+
def led( led=8, spacing: 2, round_corner: false )
|
6
|
+
|
7
|
+
width = @img.width*led + (@img.width-1)*spacing
|
8
|
+
height = @img.height*led + (@img.height-1)*spacing
|
9
|
+
|
10
|
+
puts " #{width}x#{height}"
|
11
|
+
|
12
|
+
img = Image.new( width, height, Color::BLACK )
|
13
|
+
|
14
|
+
@img.width.times do |x|
|
15
|
+
@img.height.times do |y|
|
16
|
+
pixel = @img[x,y]
|
17
|
+
pixel = Color::BLACK if pixel == Color::TRANSPARENT
|
18
|
+
led.times do |n|
|
19
|
+
led.times do |m|
|
20
|
+
## round a little - drop all four corners for now
|
21
|
+
next if round_corner &&
|
22
|
+
[[0,0],[0,1],[1,0],[1,1],[0,2],[2,0],
|
23
|
+
[0,led-1],[0,led-2],[1,led-1],[1,led-2],[0,led-3],[2,led-1],
|
24
|
+
[led-1,0],[led-1,1],[led-2,0],[led-2,1],[led-1,2],[led-3,0],
|
25
|
+
[led-1,led-1],[led-1,led-2],[led-2,led-1],[led-2,led-2],[led-1,led-3],[led-3,led-1],
|
26
|
+
].include?( [n,m] )
|
27
|
+
img[x*led+n + spacing*x,
|
28
|
+
y*led+m + spacing*y] = pixel
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
img
|
34
|
+
end
|
35
|
+
end # class Image
|
36
|
+
end # module Pixelart
|
37
|
+
|
data/lib/pixelart/misc.rb
CHANGED
@@ -15,6 +15,9 @@ class ImagePalette8bit < Image # or use Palette256 alias?
|
|
15
15
|
img = ChunkyPNG::Image.new( 32*size+(32-1)*spacing,
|
16
16
|
8*size+(8-1)*spacing )
|
17
17
|
|
18
|
+
|
19
|
+
colors =colors.map {|color| Color.parse( color ) }
|
20
|
+
|
18
21
|
colors.each_with_index do |color,i|
|
19
22
|
y,x = i.divmod( 32 )
|
20
23
|
if size > 1
|
@@ -32,6 +35,32 @@ class ImagePalette8bit < Image # or use Palette256 alias?
|
|
32
35
|
super( img.width, img.height, img )
|
33
36
|
end
|
34
37
|
end # class ImagePalette8bit
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
class ImageColorBar < Image
|
42
|
+
## make a color bar
|
43
|
+
## keep auto-zoom 24x or such - why? why not?
|
44
|
+
def initialize( colors, size: 24 )
|
45
|
+
img = ChunkyPNG::Image.new( colors.size*size,
|
46
|
+
size,
|
47
|
+
ChunkyPNG::Color::WHITE ) # why? why not?
|
48
|
+
|
49
|
+
colors = colors.map {|color| Color.parse( color ) }
|
50
|
+
|
51
|
+
colors.each_with_index do |color,i|
|
52
|
+
size.times do |x|
|
53
|
+
size.times do |y|
|
54
|
+
img[x+size*i,y] = color
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
super( img.width, img.height, img )
|
60
|
+
end
|
61
|
+
end # class ImageColorBar
|
62
|
+
|
63
|
+
|
35
64
|
end # module Pixelart
|
36
65
|
|
37
66
|
|
@@ -0,0 +1,165 @@
|
|
1
|
+
module Pixelart
|
2
|
+
|
3
|
+
|
4
|
+
class Pixelator # or use Minifier or such - rename - why? why not?
|
5
|
+
|
6
|
+
def initialize( img, width=24, height=24 )
|
7
|
+
@img = img.is_a?( Image ) ? img.image : img ## "unwrap" if Pixelart::Image
|
8
|
+
@width = width
|
9
|
+
@height = height
|
10
|
+
|
11
|
+
## calculate pixel size / density / resolution
|
12
|
+
## how many pixels per pixel?
|
13
|
+
@xsize, @xoverflow = img.width.divmod( width )
|
14
|
+
@ysize, @yoverflow = img.height.divmod( height )
|
15
|
+
|
16
|
+
puts "minify image size from (#{@img.width}x#{@img.height}) to (#{width}x#{height})"
|
17
|
+
puts " pixel size (#{@xsize}x#{@ysize}) - #{@xsize*@ysize} pixel(s) per pixel"
|
18
|
+
puts " overflow x: #{@xoverflow}, y: #{@yoverflow} pixel(s)" if @xoverflow > 0 || @yoverflow > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def grid( spacing: 10 )
|
23
|
+
width = @img.width + (@width-1)*spacing
|
24
|
+
height = @img.height + (@height-1)*spacing
|
25
|
+
|
26
|
+
img = ChunkyPNG::Image.new( width, height, ChunkyPNG::Color::WHITE )
|
27
|
+
|
28
|
+
@img.width.times do |x|
|
29
|
+
xpixel = x/@xsize
|
30
|
+
@img.height.times do |y|
|
31
|
+
ypixel = y/@ysize
|
32
|
+
|
33
|
+
## clip overflow pixels
|
34
|
+
xpixel = @width-1 if xpixel >= @width
|
35
|
+
ypixel = @height-1 if ypixel >= @height
|
36
|
+
|
37
|
+
color = @img[x,y]
|
38
|
+
img[x + spacing*xpixel,
|
39
|
+
y + spacing*ypixel] = color
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Image.new( img.width, img.height, img ) ## wrap in Pixelart::Image - why? why not?
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# pixels by coordinates (x/y) with color statistics / usage
|
48
|
+
def pixels
|
49
|
+
@pixels ||= begin
|
50
|
+
pixels = []
|
51
|
+
@img.width.times do |x|
|
52
|
+
xpixel = x/@xsize
|
53
|
+
@img.height.times do |y|
|
54
|
+
ypixel = y/@ysize
|
55
|
+
|
56
|
+
## skip/cut off overflow pixels
|
57
|
+
next if xpixel >= @width || ypixel >= @height
|
58
|
+
|
59
|
+
color = @img[x,y]
|
60
|
+
colors = pixels[xpixel+ypixel*@width] ||= Hash.new(0)
|
61
|
+
colors[ color ] += 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
## sort pixel colors by usage / count (highest first)
|
66
|
+
pixels = pixels.map do |pixel|
|
67
|
+
pixel.sort do |l,r|
|
68
|
+
r[1] <=> l[1]
|
69
|
+
end.to_h
|
70
|
+
end
|
71
|
+
pixels
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def pixel(x,y) pixels[x+y*@width]; end
|
76
|
+
alias_method :[], :pixel
|
77
|
+
|
78
|
+
|
79
|
+
def can_pixelate?( threshold: 50 )
|
80
|
+
# check if any pixel has NOT a color with a 50% majority?
|
81
|
+
count = 0
|
82
|
+
@width.times do |x|
|
83
|
+
@height.times do |y|
|
84
|
+
pixel = pixel( x, y )
|
85
|
+
sum = pixel.values.sum
|
86
|
+
color_count = pixel.values[0]
|
87
|
+
|
88
|
+
threshold_count = sum / (100/threshold)
|
89
|
+
if color_count < threshold_count
|
90
|
+
count += 1
|
91
|
+
puts "!! #{color_count} < #{threshold_count} (#{threshold}%)"
|
92
|
+
## todo/check: stor warn in a public errors or warns array - why? why not?
|
93
|
+
puts "!! WARN #{count} - pixel (#{x}/#{y}) - no majority (#{threshold}%) color:"
|
94
|
+
pp pixel
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
count == 0 ## return true if not warnings found
|
100
|
+
end
|
101
|
+
alias_method :pixelate?, :can_pixelate?
|
102
|
+
|
103
|
+
|
104
|
+
def pixelate
|
105
|
+
img = ChunkyPNG::Image.new( @width, @height )
|
106
|
+
|
107
|
+
@width.times do |x|
|
108
|
+
@height.times do |y|
|
109
|
+
pixel = pixel( x, y )
|
110
|
+
color = pixel.keys[0]
|
111
|
+
img[x,y] = color
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
Image.new( img.width, img.height, img ) ## wrap in Pixelart::Image - why? why not?
|
116
|
+
end
|
117
|
+
|
118
|
+
def outline
|
119
|
+
## create a two color outline (transparent and non-transparent color)
|
120
|
+
img = ChunkyPNG::Image.new( @width, @height )
|
121
|
+
|
122
|
+
@width.times do |x|
|
123
|
+
@height.times do |y|
|
124
|
+
pixel = pixel( x, y )
|
125
|
+
## calculate pixel count for transparent and non-transparent parts
|
126
|
+
## note:
|
127
|
+
## also count all colors with alpha channel < 200 to transparent!!
|
128
|
+
transparent_count, color_count = pixel.reduce([0,0]) do |mem, (color,count)|
|
129
|
+
hsl = Color.to_hsl( color )
|
130
|
+
## get alpha channel (transparency) for hsla
|
131
|
+
## 0-255 max.
|
132
|
+
alpha = hsl[3]
|
133
|
+
if color == 0x00 || alpha < 200
|
134
|
+
mem[0] += count
|
135
|
+
else
|
136
|
+
mem[1] += count
|
137
|
+
end
|
138
|
+
mem
|
139
|
+
end
|
140
|
+
|
141
|
+
print "."
|
142
|
+
if transparent_count > 0 && color_count > 0
|
143
|
+
print "(#{x}/#{y}=>#{transparent_count}/#{color_count})"
|
144
|
+
end
|
145
|
+
|
146
|
+
## todo/check:
|
147
|
+
## warn if sum_transparent == sum_color
|
148
|
+
## or within "threshold" e.g. below 55% or 58% or such - why? why not?
|
149
|
+
## or add treshold as param to outline?
|
150
|
+
color = if transparent_count > color_count
|
151
|
+
0x0
|
152
|
+
else
|
153
|
+
0x0000ffff ## use blue for now
|
154
|
+
end
|
155
|
+
|
156
|
+
img[x,y] = color
|
157
|
+
end
|
158
|
+
end
|
159
|
+
print "\n"
|
160
|
+
|
161
|
+
Image.new( img.width, img.height, img ) ## wrap in Pixelart::Image - why? why not?
|
162
|
+
end
|
163
|
+
end # class Pixelator
|
164
|
+
end # module Pixelart
|
165
|
+
|
data/lib/pixelart/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pixelart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chunky_png
|
@@ -75,10 +75,13 @@ files:
|
|
75
75
|
- lib/pixelart.rb
|
76
76
|
- lib/pixelart/base.rb
|
77
77
|
- lib/pixelart/color.rb
|
78
|
+
- lib/pixelart/composite.rb
|
78
79
|
- lib/pixelart/gradient.rb
|
79
80
|
- lib/pixelart/image.rb
|
81
|
+
- lib/pixelart/led.rb
|
80
82
|
- lib/pixelart/misc.rb
|
81
83
|
- lib/pixelart/palette.rb
|
84
|
+
- lib/pixelart/pixelator.rb
|
82
85
|
- lib/pixelart/version.rb
|
83
86
|
homepage: https://github.com/rubycoco/pixel
|
84
87
|
licenses:
|