pixelart 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 627a2802ea7e3ad7a10490ea4f721d57a4007669fe59a0b6cc17fb798c60b7a7
4
- data.tar.gz: 8edd801f96debe5b664f31180510ea103469f1f62e5f4ee88959046718350b7f
3
+ metadata.gz: 4ebe6ddb193d15d611f37461ebca0f7de77d9df6d14c0078eeb483fcdcaf505e
4
+ data.tar.gz: 773ab34615671bb06b4e8b8e77096cc9e44588ec5c1b04662474e410a0382223
5
5
  SHA512:
6
- metadata.gz: 8bdff35694d0212e5c48799be188b1cfeef29bd24e48f46fab6e387f5dcdcde3063105db5fd1cab21f8b03ce12c1420fb5abed0f59ae42801b57164ff6682e08
7
- data.tar.gz: de54f3cc88c6dd7e198abdba49eb7549c1ae18c018a24695ccc676dee94360b9fed68f0e415ce92060993fd1323f4c5cfd40831b5411bf7db0fb008d67951f60
6
+ metadata.gz: 50f927ae70136c40e9d8bcac7c7c87641dc51427fbf5abaf2a88f1312327e83f59689b597b91e0d9003887a349b10fd20ce4be2ba7bf7baf1b9cebd2df2ee7b5
7
+ data.tar.gz: 6afea4ef51112243f065b7071d26c4ae6a70b3c408015838ab01a02d38a3a53ff3f14f04c7cd9746520c6be10f4153eba8b6533e4a52726dc531a7d54e250c29
data/Manifest.txt CHANGED
@@ -7,6 +7,8 @@ lib/pixelart/base.rb
7
7
  lib/pixelart/color.rb
8
8
  lib/pixelart/gradient.rb
9
9
  lib/pixelart/image.rb
10
+ lib/pixelart/led.rb
10
11
  lib/pixelart/misc.rb
11
12
  lib/pixelart/palette.rb
13
+ lib/pixelart/pixelator.rb
12
14
  lib/pixelart/version.rb
data/README.md CHANGED
@@ -3,8 +3,8 @@
3
3
  pixelart - mint your own pixel art images off chain using any design (in ascii text) in any colors; incl. 2x/4x/8x zoom for bigger sizes
4
4
 
5
5
 
6
- * home :: [github.com/cryptocopycats/mooncats](https://github.com/cryptocopycats/mooncats)
7
- * bugs :: [github.com/cryptocopycats/mooncats/issues](https://github.com/cryptocopycats/mooncats/issues)
6
+ * home :: [github.com/rubycoco/pixel](https://github.com/rubycoco/pixel)
7
+ * bugs :: [github.com/rubycoco/pixel/issues](https://github.com/rubycoco/pixel/issues)
8
8
  * gem :: [rubygems.org/gems/pixelart](https://rubygems.org/gems/pixelart)
9
9
  * rdoc :: [rubydoc.info/gems/pixelart](http://rubydoc.info/gems/pixelart)
10
10
 
@@ -71,8 +71,8 @@ img3x.save( './i/mooncat_white-3x.png' )
71
71
 
72
72
  Voila!
73
73
 
74
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/mooncat_white.png)
75
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/mooncat_white-3x.png)
74
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_white.png)
75
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_white-3x.png)
76
76
 
77
77
 
78
78
 
@@ -100,8 +100,8 @@ img3x.save( './i/mooncat_black-3x.png' )
100
100
 
101
101
  Voila! Black is the new White!
102
102
 
103
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/mooncat_black.png)
104
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/mooncat_black-3x.png)
103
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_black.png)
104
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_black-3x.png)
105
105
 
106
106
 
107
107
 
@@ -227,8 +227,8 @@ img5x.save( './i/vader5x.png' )
227
227
 
228
228
  Voila!
229
229
 
230
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/vader.png)
231
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/vader5x.png)
230
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/vader.png)
231
+ ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/vader5x.png)
232
232
 
233
233
 
234
234
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ Hoe.spec 'pixelart' do
8
8
  self.summary = "pixelart - mint your own pixel art images off chain using any design (in ascii text) in any colors; incl. 2x/4x/8x zoom for bigger sizes"
9
9
  self.description = summary
10
10
 
11
- self.urls = { home: 'https://github.com/cryptocopycats/mooncats' }
11
+ self.urls = { home: 'https://github.com/rubycoco/pixel' }
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
14
  self.email = 'wwwmake@googlegroups.com'
data/lib/pixelart/base.rb CHANGED
@@ -15,8 +15,14 @@ require 'pixelart/gradient'
15
15
  require 'pixelart/palette'
16
16
  require 'pixelart/image'
17
17
 
18
+ require 'pixelart/pixelator'
19
+
18
20
  require 'pixelart/misc' ## misc helpers
19
21
 
22
+ require 'pixelart/led' ## (special) effects / filters
23
+
24
+
25
+
20
26
 
21
27
  ##########
22
28
  # add some spelling convenience variants
@@ -25,9 +31,8 @@ PixelArt = Pixelart
25
31
  module Pixelart
26
32
  Palette256 = Palette8Bit = Palette8bit
27
33
 
28
- class Image
29
- Palette256 = Palette8Bit = Palette8bit
30
- end
34
+ Palette256Image = Palette8BitImage = Palette8bitImage =
35
+ ImagePalette256 = ImagePalette8Bit = ImagePalette8bit
31
36
  end
32
37
 
33
38
 
@@ -7,7 +7,6 @@ class Color
7
7
  WHITE = 0xffffffff # rgba(255,255,255,255)
8
8
 
9
9
 
10
-
11
10
  def self.parse( color )
12
11
  if color.is_a?( Integer ) ## e.g. assumes ChunkyPNG::Color.rgb() or such
13
12
  color ## pass through as is 1:1
@@ -9,7 +9,14 @@ def self.read( path ) ## convenience helper
9
9
  end
10
10
 
11
11
 
12
- def self.parse( pixels, colors: )
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 = colors[color]
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
@@ -98,7 +117,7 @@ PALETTE8BIT = {
98
117
 
99
118
  def change_palette8bit( palette )
100
119
  ## step 0: mapping from grayscale to new 8bit palette (256 colors)
101
- color_map = if palette.is_a( String ) || palette.is_a( Symbol )
120
+ color_map = if palette.is_a?( String ) || palette.is_a?( Symbol )
102
121
  PALETTE8BIT[ palette.to_sym ]
103
122
  ## todo/fix: check for missing/undefined palette not found - why? why not?
104
123
  else
@@ -170,6 +189,9 @@ def []=( x, y, value ) @img[x,y]=value; end
170
189
 
171
190
  def pixels() @img.pixels; end
172
191
 
192
+ ### todo/check: add colors() e.g. @img.pixels.uniq - why? why not?
193
+
194
+
173
195
  ## return image ref - use a different name - why? why not?
174
196
  ## change to to_image - why? why not?
175
197
  def image() @img; end
@@ -183,10 +205,7 @@ def self.parse_pixels( pixels )
183
205
  data = []
184
206
  pixels.each_line do |line|
185
207
  line = line.strip
186
- if line.empty?
187
- puts "!! WARN: skipping empty line in pixel art source"
188
- next
189
- end
208
+ next if line.start_with?( '#' ) || line.empty? ## note: allow comments and empty lines
190
209
 
191
210
  ## note: allow multiple spaces or tabs to separate pixel codes
192
211
  ## 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 +216,13 @@ def self.parse_pixels( pixels )
197
216
  end
198
217
 
199
218
 
219
+
200
220
  def self.parse_colors( colors )
201
221
  if colors.is_a?( Array ) ## convenience shortcut
202
222
  ## note: always auto-add color 0 as pre-defined transparent - why? why not?
203
223
  h = { '0' => Color::TRANSPARENT }
204
224
  colors.each_with_index do |color, i|
205
- h[ (i+1).to_s ] = Color.parse( color )
225
+ h[ (i+1).to_s ] = Color.parse( color )
206
226
  end
207
227
  h
208
228
  else ## assume hash table with color map
@@ -215,7 +235,6 @@ def self.parse_colors( colors )
215
235
  end
216
236
 
217
237
 
218
-
219
238
  end # class Image
220
239
  end # module Pixelart
221
240
 
@@ -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
@@ -1,8 +1,7 @@
1
1
  module Pixelart
2
2
 
3
3
 
4
- class Image
5
- class Palette8bit < Image # or use Palette256 alias?
4
+ class ImagePalette8bit < Image # or use Palette256 alias?
6
5
  def initialize( colors, size: 1, spacing: nil )
7
6
  ## todo/check: change size arg to pixel or such? better name/less confusing - why? why not?
8
7
 
@@ -16,6 +15,9 @@ class Palette8bit < Image # or use Palette256 alias?
16
15
  img = ChunkyPNG::Image.new( 32*size+(32-1)*spacing,
17
16
  8*size+(8-1)*spacing )
18
17
 
18
+
19
+ colors =colors.map {|color| Color.parse( color ) }
20
+
19
21
  colors.each_with_index do |color,i|
20
22
  y,x = i.divmod( 32 )
21
23
  if size > 1
@@ -32,9 +34,33 @@ class Palette8bit < Image # or use Palette256 alias?
32
34
 
33
35
  super( img.width, img.height, img )
34
36
  end
35
- end # class Palette8bit
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
+
36
63
 
37
- end # class Image
38
64
  end # module Pixelart
39
65
 
40
66
 
@@ -0,0 +1,117 @@
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?
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
+ if color_count < (sum/2)
88
+ count += 1
89
+ ## todo/check: stor warn in a public errors or warns array - why? why not?
90
+ puts "!! WARN #{count} - pixel (#{x}/#{y}) - no majority (50%) color:"
91
+ pp pixel
92
+ end
93
+ end
94
+ end
95
+
96
+ count == 0 ## return true if not warnings found
97
+ end
98
+ alias_method :pixelate?, :can_pixelate?
99
+
100
+
101
+ def pixelate
102
+ img = ChunkyPNG::Image.new( @width, @height )
103
+
104
+ @width.times do |x|
105
+ @height.times do |y|
106
+ pixel = pixel( x, y )
107
+ color = pixel.keys[0]
108
+ img[x,y] = color
109
+ end
110
+ end
111
+
112
+ Image.new( img.width, img.height, img ) ## wrap in Pixelart::Image - why? why not?
113
+ end
114
+ end # class Pixelator
115
+ end # module Pixelart
116
+
117
+
@@ -2,8 +2,8 @@
2
2
  module Pixelart
3
3
 
4
4
  MAJOR = 0
5
- MINOR = 1
6
- PATCH = 4
5
+ MINOR = 2
6
+ PATCH = 0
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
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.1.4
4
+ version: 0.2.0
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-04-18 00:00:00.000000000 Z
11
+ date: 2021-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chunky_png
@@ -77,10 +77,12 @@ files:
77
77
  - lib/pixelart/color.rb
78
78
  - lib/pixelart/gradient.rb
79
79
  - lib/pixelart/image.rb
80
+ - lib/pixelart/led.rb
80
81
  - lib/pixelart/misc.rb
81
82
  - lib/pixelart/palette.rb
83
+ - lib/pixelart/pixelator.rb
82
84
  - lib/pixelart/version.rb
83
- homepage: https://github.com/cryptocopycats/mooncats
85
+ homepage: https://github.com/rubycoco/pixel
84
86
  licenses:
85
87
  - Public Domain
86
88
  metadata: {}