pixelart 0.1.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 68fa84133edc2cb7f9742514af4ef188e1e358b3ae408f6ffd282c4c815e1ae5
4
- data.tar.gz: 2048f7c4e4a29cf6aff876b273c25a58bb3c2ef1c9836756847c13e59f381d18
3
+ metadata.gz: 71ac76ef187b8148a547f8dd7b76f2216bdd034f2ba67f7974b6e1a98abe3992
4
+ data.tar.gz: 6b44348938795087874a80fec20a6e1f87633ff282f62804605b42cbb232e46d
5
5
  SHA512:
6
- metadata.gz: 188f2845bf2f64102829f1840eaf56ded7ba7f2f2f931e07aa951d3b29e2e82b7570cd1564a40e8afb54ecd8f040874a9e1e589a5284025836dd81adf73549d3
7
- data.tar.gz: c12fa48855d076acd7516fa02d97a5da56467ce8ce78e7dc41e305681be1e1251fdb82ce638d6921726d5d6455e2849a75806730f314b93efe2146a70eb89d7c
6
+ metadata.gz: d94abebcda0b1d87bdc0bcdc0f6072d7ae88efed8b26a0733f4fcdccb9b8063068b9a55f24bf08ebe34705e30298ebaf5d1f619045e37fe5be3b2412a8019932
7
+ data.tar.gz: 63be655c80cf3703499aae7984a901888ca2ae3fe362ea66f5324e7abd98a0b207f5a150da9f2f1c6b7b2c29d52b71e44d252b6323eb8050160bac8c52e542f0
data/Manifest.txt CHANGED
@@ -3,4 +3,5 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/pixelart.rb
6
+ lib/pixelart/image.rb
6
7
  lib/pixelart/version.rb
data/README.md CHANGED
@@ -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/pixelarti/mooncat_white.png)
75
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelarti/mooncat_white-3x.png)
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)
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/pixelarti/mooncat_black.png)
104
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelarti/mooncat_black-3x.png)
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)
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/pixelarti/vader.png)
231
- ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelarti/vader5x.png)
230
+ ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/vader.png)
231
+ ![](https://github.com/cryptocopycats/mooncats/raw/master/pixelart/i/vader5x.png)
232
232
 
233
233
 
234
234
 
data/lib/pixelart.rb CHANGED
@@ -10,166 +10,10 @@ require 'fileutils'
10
10
 
11
11
  ## our own code
12
12
  require 'pixelart/version' # note: let version always go first
13
+ require 'pixelart/image'
13
14
 
14
15
 
15
16
 
16
- module Pixelart
17
- class Image
18
-
19
-
20
-
21
- def self.read( path ) ## convenience helper
22
- img_inner = ChunkyPNG::Image.from_file( path )
23
- img = new( img_inner.width, img_inner.height, img_inner )
24
- img
25
- end
26
-
27
-
28
- def self.parse( pixels, colors: )
29
- colors = parse_colors( colors )
30
- pixels = parse_pixels( pixels )
31
-
32
- width = pixels.reduce(1) {|width,row| row.size > width ? row.size : width }
33
- height = pixels.size
34
-
35
- img = new( width, height )
36
-
37
- pixels.each_with_index do |row,y|
38
- row.each_with_index do |color,x|
39
- pixel = colors[color]
40
- img[x,y] = pixel
41
- end # each row
42
- end # each data
43
-
44
- img
45
- end
46
-
47
-
48
-
49
- def initialize( width, height, initial=ChunkyPNG::Color::TRANSPARENT )
50
-
51
- if initial.is_a?( ChunkyPNG::Image )
52
- @img = initial
53
- else
54
- ## todo/check - initial - use parse_color here too e.g. allow "#fff" too etc.
55
- @img = ChunkyPNG::Image.new( width, height, initial )
56
- end
57
- end
58
-
59
-
60
-
61
- def zoom( zoom=2 )
62
- ## create a new zoom factor x image (2x, 3x, etc.)
63
-
64
- img = Image.new( @img.width*zoom,
65
- @img.height*zoom )
66
-
67
- @img.height.times do |y|
68
- @img.width.times do |x|
69
- pixel = @img[x,y]
70
- zoom.times do |n|
71
- zoom.times do |m|
72
- img[n+zoom*x,m+zoom*y] = pixel
73
- end
74
- end
75
- end # each x
76
- end # each y
77
-
78
- img
79
- end
80
- alias_method :scale, :zoom
81
-
82
-
83
-
84
-
85
- #####
86
- # (image) delegates
87
- ## todo/check: add some more??
88
- def save( path, constraints = {} )
89
- # step 1: make sure outdir exits
90
- outdir = File.dirname( path )
91
- FileUtils.mkdir_p( outdir ) unless Dir.exist?( outdir )
92
-
93
- # step 2: save
94
- @img.save( path, constraints )
95
- end
96
- alias_method :write, :save
97
-
98
-
99
- def compose!( other, x=0, y=0 )
100
- @img.compose!( other.image, x, y ) ## note: "unwrap" inner image ref
101
- end
102
- alias_method :paste!, :compose!
103
-
104
-
105
- def width() @img.width; end
106
- def height() @img.height; end
107
-
108
- def []( x, y ) @img[x,y]; end
109
- def []=( x, y, value ) @img[x,y]=value; end
110
-
111
- ## return image ref - use a different name - why? why not?
112
- def image() @img; end
113
-
114
-
115
-
116
-
117
- ######
118
- # helpers
119
- def self.parse_pixels( pixels )
120
- data = []
121
- pixels.each_line do |line|
122
- line = line.strip
123
- if line.empty?
124
- puts "!! WARN: skipping empty line in pixel art source"
125
- next
126
- end
127
-
128
- ## note: allow multiple spaces or tabs to separate pixel codes
129
- ## 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
130
- ## or
131
- data << line.split( /[ \t]+/)
132
- end
133
- data
134
- end
135
-
136
-
137
- def self.parse_colors( colors )
138
- if colors.is_a?( Array ) ## convenience shortcut
139
- ## note: always auto-add color 0 as pre-defined transparent - why? why not?
140
- h = { '0' => ChunkyPNG::Color::TRANSPARENT }
141
- colors.each_with_index do |color, i|
142
- h[ (i+1).to_s ] = parse_color( color )
143
- end
144
- h
145
- else ## assume hash table with color map
146
- ## convert into ChunkyPNG::Color
147
- colors.map do |key,color|
148
- ## always convert key to string why? why not? use symbol?
149
- [ key.to_s, parse_color( color ) ]
150
- end.to_h
151
- end
152
- end
153
-
154
- def self.parse_color( color )
155
- if color.is_a?( Integer ) ## e.g. Assumess ChunkyPNG::Color.rgb() or such
156
- color ## pass through as is 1:1
157
- elsif color.is_a?(String)
158
- if color.downcase == 'transparent' ## special case for builtin colors
159
- ChunkyPNG::Color::TRANSPARENT
160
- else
161
- ## note: return an Integer !!! (not a Color class or such!!! )
162
- ChunkyPNG::Color.from_hex( color )
163
- end
164
- else
165
- raise ArgumentError, "unknown color format; cannot parse - expected rgb hex string e.g. d3d3d3"
166
- end
167
- end
168
-
169
-
170
- end # class Image
171
- end # module Pixelart
172
-
173
17
 
174
18
 
175
19
  ### add some convenience shortcuts
@@ -0,0 +1,225 @@
1
+ module Pixelart
2
+
3
+
4
+
5
+
6
+ class Color
7
+ def self.parse( color )
8
+ if color.is_a?( Integer ) ## e.g. assumes ChunkyPNG::Color.rgb() or such
9
+ color ## pass through as is 1:1
10
+ elsif color.is_a?( Array ) ## assume array of hsl(a) e. g. [180, 0.86, 0.88]
11
+ ChunkyPNG::Color.from_hsl( *color )
12
+ elsif color.is_a?( String )
13
+ if color.downcase == 'transparent' ## special case for builtin colors
14
+ ChunkyPNG::Color::TRANSPARENT
15
+ else
16
+ ## note: return an Integer !!! (not a Color class or such!!! )
17
+ ChunkyPNG::Color.from_hex( color )
18
+ end
19
+ else
20
+ raise ArgumentError, "unknown color format; cannot parse - expected rgb hex string e.g. d3d3d3"
21
+ end
22
+ end
23
+
24
+ def self.from_hex( hex )
25
+ ## Creates a color by converting it from a string in hex notation.
26
+ ##
27
+ ## It supports colors with (#rrggbbaa) or without (#rrggbb)
28
+ ## alpha channel as well as the 3-digit short format (#rgb)
29
+ ## for those without. Color strings may include
30
+ ## the prefix "0x" or "#"".
31
+ ChunkyPNG::Color.from_hex( hex )
32
+ end
33
+
34
+ def self.from_hsl( hue, saturation, lightness, alpha=255)
35
+ ChunkyPNG::Color.from_hsl( hue,
36
+ saturation,
37
+ lightness,
38
+ alpha )
39
+ end
40
+
41
+
42
+ def self.to_hex( color, include_alpha: true )
43
+ ChunkyPNG::Color.to_hex( color, include_alpha )
44
+ end
45
+
46
+ def self.to_hsl( color, include_alpha: true )
47
+ # Returns an array with the separate HSL components of a color.
48
+ ChunkyPNG::Color.to_hsl( color, include_alpha )
49
+ end
50
+ end # class Color
51
+
52
+
53
+
54
+
55
+ class Image
56
+
57
+ def self.read( path ) ## convenience helper
58
+ img_inner = ChunkyPNG::Image.from_file( path )
59
+ img = new( img_inner.width, img_inner.height, img_inner )
60
+ img
61
+ end
62
+
63
+
64
+ def self.parse( pixels, colors: )
65
+ colors = parse_colors( colors )
66
+ pixels = parse_pixels( pixels )
67
+
68
+ width = pixels.reduce(1) {|width,row| row.size > width ? row.size : width }
69
+ height = pixels.size
70
+
71
+ img = new( width, height )
72
+
73
+ pixels.each_with_index do |row,y|
74
+ row.each_with_index do |color,x|
75
+ pixel = colors[color]
76
+ img[x,y] = pixel
77
+ end # each row
78
+ end # each data
79
+
80
+ img
81
+ end
82
+
83
+
84
+
85
+ def initialize( width, height, initial=ChunkyPNG::Color::TRANSPARENT )
86
+
87
+ if initial.is_a?( ChunkyPNG::Image )
88
+ @img = initial
89
+ else
90
+ ## todo/check - initial - use parse_color here too e.g. allow "#fff" too etc.
91
+ @img = ChunkyPNG::Image.new( width, height, initial )
92
+ end
93
+ end
94
+
95
+
96
+
97
+ def zoom( zoom=2 )
98
+ ## create a new zoom factor x image (2x, 3x, etc.)
99
+
100
+ img = Image.new( @img.width*zoom,
101
+ @img.height*zoom )
102
+
103
+ @img.height.times do |y|
104
+ @img.width.times do |x|
105
+ pixel = @img[x,y]
106
+ zoom.times do |n|
107
+ zoom.times do |m|
108
+ img[n+zoom*x,m+zoom*y] = pixel
109
+ end
110
+ end
111
+ end # each x
112
+ end # each y
113
+
114
+ img
115
+ end
116
+ alias_method :scale, :zoom
117
+
118
+
119
+
120
+
121
+ def parse_color_map( color_map )
122
+ color_map.map do |k,v|
123
+ [Color.parse(k), Color.parse(v)]
124
+ end.to_h
125
+ end
126
+
127
+ ## add replace_colors alias too? - why? why not?
128
+ def change_colors( color_map )
129
+ img = @img.dup ## note: make a deep copy!!!
130
+ color_map = parse_color_map( color_map )
131
+ ## pp color_map
132
+
133
+ img.width.times do |x|
134
+ img.height.times do |y|
135
+ color = img[x,y]
136
+ new_color = color_map[color]
137
+ img[x,y] = new_color if new_color
138
+ end
139
+ end
140
+
141
+ ## wrap into Pixelart::Image - lets you use zoom() and such
142
+ Image.new( img.width, img.height, img )
143
+ end
144
+ alias_method :recolor, :change_colors
145
+
146
+
147
+
148
+
149
+
150
+ #####
151
+ # (image) delegates
152
+ ## todo/check: add some more??
153
+ def save( path, constraints = {} )
154
+ # step 1: make sure outdir exits
155
+ outdir = File.dirname( path )
156
+ FileUtils.mkdir_p( outdir ) unless Dir.exist?( outdir )
157
+
158
+ # step 2: save
159
+ @img.save( path, constraints )
160
+ end
161
+ alias_method :write, :save
162
+
163
+
164
+ def compose!( other, x=0, y=0 )
165
+ @img.compose!( other.image, x, y ) ## note: "unwrap" inner image ref
166
+ end
167
+ alias_method :paste!, :compose!
168
+
169
+
170
+ def width() @img.width; end
171
+ def height() @img.height; end
172
+
173
+ def []( x, y ) @img[x,y]; end
174
+ def []=( x, y, value ) @img[x,y]=value; end
175
+
176
+ def pixels() @img.pixels; end
177
+
178
+ ## return image ref - use a different name - why? why not?
179
+ def image() @img; end
180
+
181
+
182
+
183
+
184
+ ######
185
+ # helpers
186
+ def self.parse_pixels( pixels )
187
+ data = []
188
+ pixels.each_line do |line|
189
+ line = line.strip
190
+ if line.empty?
191
+ puts "!! WARN: skipping empty line in pixel art source"
192
+ next
193
+ end
194
+
195
+ ## note: allow multiple spaces or tabs to separate pixel codes
196
+ ## 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
+ ## or
198
+ data << line.split( /[ \t]+/)
199
+ end
200
+ data
201
+ end
202
+
203
+
204
+ def self.parse_colors( colors )
205
+ if colors.is_a?( Array ) ## convenience shortcut
206
+ ## note: always auto-add color 0 as pre-defined transparent - why? why not?
207
+ h = { '0' => ChunkyPNG::Color::TRANSPARENT }
208
+ colors.each_with_index do |color, i|
209
+ h[ (i+1).to_s ] = Color.parse( color )
210
+ end
211
+ h
212
+ else ## assume hash table with color map
213
+ ## convert into ChunkyPNG::Color
214
+ colors.map do |key,color|
215
+ ## always convert key to string why? why not? use symbol?
216
+ [ key.to_s, Color.parse( color ) ]
217
+ end.to_h
218
+ end
219
+ end
220
+
221
+
222
+
223
+ end # class Image
224
+ end # module Pixelart
225
+
@@ -3,7 +3,7 @@ module Pixelart
3
3
 
4
4
  MAJOR = 0
5
5
  MINOR = 1
6
- PATCH = 1
6
+ PATCH = 2
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.1
4
+ version: 0.1.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-04-12 00:00:00.000000000 Z
11
+ date: 2021-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chunky_png
@@ -73,6 +73,7 @@ files:
73
73
  - README.md
74
74
  - Rakefile
75
75
  - lib/pixelart.rb
76
+ - lib/pixelart/image.rb
76
77
  - lib/pixelart/version.rb
77
78
  homepage: https://github.com/cryptocopycats/mooncats
78
79
  licenses: