pixelart 1.2.0 → 1.2.3

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: 798a4eb7b61556c0c79889d01d404a499598286779e009fa71304986f4d68c31
4
- data.tar.gz: 9b17446fe914c1b62135c1e1432bc2debf74037ca9e602feb25e71ec7088b117
3
+ metadata.gz: cfdb6f457e12b2e76af0f8ad601d884e763b111a42031cb4ca687026e26fec9d
4
+ data.tar.gz: 920c3d4d76effc32b6b37c865f960bd1d9b2a5711d5355a5ec681f2d0d38778f
5
5
  SHA512:
6
- metadata.gz: 8073e67ffd10361088fd66b768d4aa5927c2f65cdd54389615b980c2181ec8cde2a2ad21eced1fe7a756af7ce2e7c681b2aea4a89aed2c869ad04a956388d54a
7
- data.tar.gz: b69918e012f6270a9aa0817d69e094bb52cd12ed05399ac566872efdd2174af9c9534ef2e72f4f34f4d3f1bbe4d5062aedcbb42deb67ff55c52a005965b2d969
6
+ metadata.gz: a584e986e1ada98617770a43979bd0f808105aac525e947e23549c5ad2dc89cfd3445380dce8773cbf8a9682c49e0ffba35642270c27db33ac76315c744ef203
7
+ data.tar.gz: c427b35da5186c6505af7364c64c71992174b8f5c3c7ea4330d8599caa55d6d7ef7554f0e154401eb8602c924be6045249af8212c76be37b7da60ca930c8a49c
data/Manifest.txt CHANGED
@@ -5,6 +5,7 @@ Rakefile
5
5
  lib/pixelart.rb
6
6
  lib/pixelart/base.rb
7
7
  lib/pixelart/blur.rb
8
+ lib/pixelart/circle.rb
8
9
  lib/pixelart/color.rb
9
10
  lib/pixelart/composite.rb
10
11
  lib/pixelart/gradient.rb
@@ -13,7 +14,10 @@ lib/pixelart/led.rb
13
14
  lib/pixelart/misc.rb
14
15
  lib/pixelart/palette.rb
15
16
  lib/pixelart/pixelator.rb
17
+ lib/pixelart/silhouette.rb
16
18
  lib/pixelart/sketch.rb
17
19
  lib/pixelart/spots.rb
20
+ lib/pixelart/transparent.rb
21
+ lib/pixelart/ukraine.rb
18
22
  lib/pixelart/vector.rb
19
23
  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/rubycoco/pixel](https://github.com/rubycoco/pixel)
7
- * bugs :: [github.com/rubycoco/pixel/issues](https://github.com/rubycoco/pixel/issues)
6
+ * home :: [github.com/pixelartexchange/pixel](https://github.com/pixelartexchange/pixel)
7
+ * bugs :: [github.com/pixelartexchange/pixel/issues](https://github.com/pixelartexchange/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/rubycoco/pixel/raw/master/pixelart/i/mooncat_white.png)
75
- ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_white-3x.png)
74
+ ![](https://github.com/pixelartexchange/pixel/raw/master/pixelart/i/mooncat_white.png)
75
+ ![](https://github.com/pixelartexchange/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/rubycoco/pixel/raw/master/pixelart/i/mooncat_black.png)
104
- ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/mooncat_black-3x.png)
103
+ ![](https://github.com/pixelartexchange/pixel/raw/master/pixelart/i/mooncat_black.png)
104
+ ![](https://github.com/pixelartexchange/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/rubycoco/pixel/raw/master/pixelart/i/vader.png)
231
- ![](https://github.com/rubycoco/pixel/raw/master/pixelart/i/vader5x.png)
230
+ ![](https://github.com/pixelartexchange/pixel/raw/master/pixelart/i/vader.png)
231
+ ![](https://github.com/pixelartexchange/pixel/raw/master/pixelart/i/vader5x.png)
232
232
 
233
233
 
234
234
 
@@ -288,4 +288,3 @@ Just install the gem:
288
288
 
289
289
  The scripts are dedicated to the public domain.
290
290
  Use it as you please with no restrictions whatsoever.
291
-
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/rubycoco/pixel' }
11
+ self.urls = { home: 'https://github.com/pixelartexchange/pixel' }
12
12
 
13
13
  self.author = 'Gerald Bauer'
14
14
  self.email = 'wwwmake@googlegroups.com'
@@ -20,6 +20,7 @@ Hoe.spec 'pixelart' do
20
20
  self.extra_deps = [
21
21
  ['chunky_png'],
22
22
  ['mini_magick'],
23
+ ['csvreader'],
23
24
  ]
24
25
 
25
26
  self.licenses = ['Public Domain']
data/lib/pixelart/base.rb CHANGED
@@ -7,6 +7,9 @@ require 'chunky_png'
7
7
  require 'mini_magick'
8
8
 
9
9
 
10
+ # bonus / prologue / convenience 3rd party
11
+ require 'csvreader'
12
+
10
13
 
11
14
  ## stdlib
12
15
  require 'pp'
@@ -34,9 +37,14 @@ require 'pixelart/pixelator'
34
37
  require 'pixelart/misc' ## misc helpers
35
38
 
36
39
  #########################
37
- # (special) effects / filters
40
+ # (special) effects / filters / etc
41
+ require 'pixelart/circle'
38
42
  require 'pixelart/led'
39
43
  require 'pixelart/sketch'
44
+ require 'pixelart/transparent'
45
+ require 'pixelart/silhouette'
46
+ require 'pixelart/ukraine'
47
+
40
48
 
41
49
  ## (special) effects / filters that require imagemagick
42
50
 
@@ -0,0 +1,46 @@
1
+ ###
2
+ #
3
+ # add more circle aliases
4
+ # e.g. circular / round or such - why? why not?
5
+
6
+
7
+ module Pixelart
8
+
9
+ class Image
10
+ def circle
11
+ ### for radius use min of width / height
12
+ r = [@img.width, @img.height].min / 2
13
+
14
+ center_x = width / 2
15
+ center_y = height / 2
16
+
17
+ ################
18
+ # try with 96x96
19
+ # center_x: 96 / 2 = 48
20
+ # center_y: 96 / 2 = 48
21
+ #
22
+ # r: 96 / 2 = 48
23
+
24
+ img = Image.new( @img.width, @img.height )
25
+
26
+ @img.width.times do |x|
27
+ @img.height.times do |y|
28
+
29
+ ## change to float calcuation (instead of ints) - why? why not?
30
+ xx, yy, rr = x - center_x,
31
+ y - center_y,
32
+ r
33
+
34
+ img[ x, y] = if xx*xx+yy*yy < rr*rr
35
+ @img[ x, y ]
36
+ else
37
+ 0 ## transparent - alpha(0)
38
+ end
39
+ end
40
+ end
41
+
42
+ img
43
+ end
44
+ end # class Image
45
+
46
+ end # module Pixelart
@@ -18,6 +18,20 @@ class ImageComposite < Image # check: (re)name to Collage, Sheet, Sprites, or s
18
18
  @tile_width = kwargs[:width] || kwargs[:tile_width] || TILE_WIDTH
19
19
  @tile_height = kwargs[:height] || kwargs[:tile_height] || TILE_HEIGHT
20
20
 
21
+ ## check for background
22
+ background = kwargs[:background] || kwargs[:tile_background]
23
+
24
+ if background
25
+ ## wrap into an array if not already an array
26
+ ## and convert all colors to true rgba colors as integer numbers
27
+ background = [background] unless background.is_a?( Array )
28
+ @background_colors = background.map { |color| Color.parse( color ) }
29
+ else
30
+ ## todo/check: use empty array instead of nil - why? why not?
31
+ @background_colors = nil
32
+ end
33
+
34
+
21
35
  ## todo/fix: check type - args[0] is Image!!!
22
36
  if args.size == 1 ## assume "copy" c'tor with passed in image
23
37
  img = args[0] ## pass image through as-is
@@ -32,12 +46,25 @@ class ImageComposite < Image # check: (re)name to Collage, Sheet, Sprites, or s
32
46
  @tile_rows = args[1] || 3
33
47
  @tile_count = 0 # (track) current index (of added images)
34
48
 
35
- img = ChunkyPNG::Image.new( @tile_cols * @tile_width,
36
- @tile_rows * @tile_height )
49
+ background_color = if @background_colors && @background_colors.size == 1
50
+ @background_colors[0]
51
+ else
52
+ 0 # note: 0 is transparent (0) true color
53
+ end
54
+
55
+ ## todo/check - always auto-fill complete image (even if empty/no tiles)
56
+ ## with background color if only one background color
57
+ ## why? why not??? or always follow the "model"
58
+ ## with more than one background color???
59
+ img = ChunkyPNG::Image.new( @tile_cols * @tile_width,
60
+ @tile_rows * @tile_height,
61
+ background_color )
62
+
37
63
  else
38
64
  raise ArgumentError, "cols, rows or image arguments expected; got: #{args.inspect}"
39
65
  end
40
66
 
67
+
41
68
  puts " #{img.height}x#{img.width} (height x width)"
42
69
 
43
70
  super( nil, nil, img )
@@ -46,19 +73,46 @@ class ImageComposite < Image # check: (re)name to Collage, Sheet, Sprites, or s
46
73
 
47
74
  def count() @tile_count; end
48
75
  alias_method :size, :count ## add size alias (confusing if starting with 0?) - why? why not?
76
+ alias_method :tile_count, :count
77
+
78
+ def tile_width() @tile_width; end
79
+ def tile_height() @tile_height; end
80
+
81
+
49
82
 
50
83
  #####
51
84
  # set / add tile
52
-
53
- def add( image )
85
+ def _add( image )
54
86
  y, x = @tile_count.divmod( @tile_cols )
55
87
 
56
88
  puts " [#{@tile_count}] @ (#{x}/#{y}) #{image.width}x#{image.height} (height x width)"
57
89
 
90
+ ## note: only used if more than one background color specified
91
+ ## needs to cycle through
92
+ if @background_colors && @background_colors.size > 1
93
+ i = x + y*@tile_cols
94
+
95
+ ## note: cycle through background color for now
96
+ background_color = @background_colors[i % @background_colors.size]
97
+ background = Image.new( @tile_width, @tile_height, background_color ) ## todo/chekc: use "raw" ChunkyPNG:Image here - why? why not?
98
+ background.compose!( image )
99
+ image = background ## switch - make image with background new image
100
+ end
101
+
58
102
  ## note: image.image - "unwrap" the "raw" ChunkyPNG::Image
59
103
  @img.compose!( image.image, x*@tile_width, y*@tile_height )
60
104
  @tile_count += 1
61
105
  end
106
+
107
+ def add( image_or_images ) ## note: allow adding of image OR array of images
108
+ if image_or_images.is_a?( Array )
109
+ images = image_or_images
110
+ images.each { |image| _add( image ) }
111
+ else
112
+ image = image_or_images
113
+ _add( image )
114
+ end
115
+ end
62
116
  alias_method :<<, :add
63
117
 
64
118
 
@@ -64,18 +64,21 @@ end
64
64
 
65
65
 
66
66
 
67
- def zoom( zoom=2 )
67
+ def zoom( zoom=2, spacing: 0 )
68
68
  ## create a new zoom factor x image (2x, 3x, etc.)
69
69
 
70
- img = Image.new( @img.width*zoom,
71
- @img.height*zoom )
70
+ width = @img.width*zoom+(@img.width-1)*spacing
71
+ height = @img.height*zoom+(@img.height-1)*spacing
72
72
 
73
- @img.height.times do |y|
74
- @img.width.times do |x|
73
+ img = Image.new( width, height )
74
+
75
+ @img.width.times do |x|
76
+ @img.height.times do |y|
75
77
  pixel = @img[x,y]
76
78
  zoom.times do |n|
77
79
  zoom.times do |m|
78
- img[n+zoom*x,m+zoom*y] = pixel
80
+ img[n+zoom*x+spacing*x,
81
+ m+zoom*y+spacing*y] = pixel
79
82
  end
80
83
  end
81
84
  end # each x
@@ -86,6 +89,12 @@ end
86
89
  alias_method :scale, :zoom
87
90
 
88
91
 
92
+ def crop( x, y, crop_width, crop_height )
93
+ Image.new( nil, nil,
94
+ image.crop( x,y, crop_width, crop_height ) )
95
+ end
96
+
97
+
89
98
 
90
99
  #######################
91
100
  ## filter / effects
@@ -112,6 +121,17 @@ alias_method :flip_vertically, :mirror
112
121
  alias_method :flop, :mirror
113
122
 
114
123
 
124
+ def rotate_counter_clockwise # 90 degrees
125
+ img = @img.rotate_counter_clockwise
126
+ Image.new( img.width, img.height, img )
127
+ end
128
+ alias_method :rotate_left, :rotate_counter_clockwise
129
+
130
+ def rotate_clockwise # 90 degrees
131
+ img = @img.rotate_clockwise
132
+ Image.new( img.width, img.height, img )
133
+ end
134
+ alias_method :rotate_right, :rotate_clockwise
115
135
 
116
136
 
117
137
 
@@ -0,0 +1,35 @@
1
+ module Pixelart
2
+
3
+
4
+ ## todo/check:
5
+ ## use a different name for silhouette
6
+ ## - why not - outline ???
7
+ ## or - shadow ???
8
+ ## or - profile ???
9
+ ## or - figure ???
10
+ ## or - shape ???
11
+ ## or - form ???
12
+
13
+ class Image
14
+ def silhouette( color='#000000' )
15
+ color = Color.parse( color )
16
+
17
+ img = Image.new( @img.width, @img.height )
18
+
19
+ @img.width.times do |x|
20
+ @img.height.times do |y|
21
+ pixel = @img[x,y]
22
+
23
+ img[x,y] = if pixel == Color::TRANSPARENT # transparent (0)
24
+ Color::TRANSPARENT
25
+ else
26
+ color
27
+ end
28
+ end
29
+ end
30
+ img
31
+ end
32
+
33
+ end # class Image
34
+
35
+ end # module Pixelart
@@ -0,0 +1,60 @@
1
+
2
+ module Pixelart
3
+ class Image
4
+
5
+ def transparent( style = :solid, fuzzy: false )
6
+ img = Image.new( width, height )
7
+
8
+
9
+ background = self[0,0]
10
+
11
+ bh,bs,bl = Color.to_hsl( background )
12
+ bh = (bh % 360) ## might might negative degree (always make positive)
13
+
14
+ height.times do |y|
15
+ if style == :linear
16
+ background = self[0,y]
17
+
18
+ bh,bs,bl = Color.to_hsl( background )
19
+ bh = (bh % 360) ## might might negative degree (always make positive)
20
+ end
21
+ width.times do |x|
22
+ pixel = self[x,y]
23
+
24
+ if background == 0 ## special case if background is already transparent keep going
25
+ img[x,y] = pixel
26
+ elsif fuzzy
27
+ ## check for more transparents
28
+ ## not s is 0.0 to 0.99 (100%)
29
+ ## and l is 0.0 to 0.99 (100%)
30
+ h,s,l = Color.to_hsl( pixel )
31
+ h = (h % 360) ## might might negative degree (always make positive)
32
+
33
+ ## try some kind-of fuzzy "heuristic" match on background color
34
+ if ((h >= bh-5) && (h <= bh+5)) &&
35
+ ((s >= bs-0.07) && (s <= bs+0.07)) &&
36
+ ((l >= bl-0.07) && (l <= bl+0.07))
37
+ img[x,y] = 0 ## Color::TRANSPARENT
38
+
39
+ if h != bh || s != bs || l != bl
40
+ # report fuzzy background color
41
+ puts " #{x}/#{y} fuzzy background #{[h,s,l]} ~= #{[bh,bs,bl]}"
42
+ end
43
+ else
44
+ img[x,y] = pixel
45
+ end
46
+ else
47
+ if pixel == background
48
+ img[x,y] = 0 ## Color::TRANSPARENT
49
+ else
50
+ img[x,y] = pixel
51
+ end
52
+ end
53
+ end
54
+ end
55
+ img
56
+ end # method transparent
57
+
58
+
59
+ end # class Image
60
+ end # module Pixelart
@@ -0,0 +1,33 @@
1
+ #######
2
+ #
3
+ # Glory To Ukraine! Fuck (Vladimir) Putin! Stop the War!
4
+ # Send A Stop The War Message To The World With Your Pixel Art Images
5
+ #
6
+
7
+
8
+ module Pixelart
9
+
10
+ class Image
11
+ def ukraine
12
+ ### move colors to (reusable) constants e.g.
13
+ ### UKRAINE_BLUE
14
+ ### UKRAINE_YELLOW - why? why not?
15
+ ukraine_blue = Color.parse( '#0057b7' )
16
+ ukraine_yellow = Color.parse( '#ffdd00' )
17
+
18
+ img = Image.new( @img.width, @img.height )
19
+
20
+ @img.height.times do |y|
21
+ color = (y < @img.height/2) ? ukraine_blue : ukraine_yellow
22
+ @img.width.times do |x|
23
+ img[x,y] = color
24
+ end
25
+ end
26
+
27
+ img.compose!( self ) ## paste/compose image onto backgorund
28
+ img
29
+ end
30
+ end # class Image
31
+
32
+ end # module Pixelart
33
+
@@ -25,6 +25,53 @@ class Vector # holds a vector graphics image (in source)
25
25
  end
26
26
  end # class Circle
27
27
 
28
+ class Path < Shape
29
+ def initialize( fill:, stroke: )
30
+ @commands = []
31
+ @fill = fill
32
+ @stroke = stroke
33
+ end
34
+
35
+ def move_to( x, y ) ## add a move_to instruction
36
+ @commands << ['M', x, y]
37
+ self
38
+ end
39
+
40
+ def line_to( x, y )
41
+ @commands << ['L', x, y]
42
+ self
43
+ end
44
+
45
+ def line( *coords ) ## move_to/line_to all-in-one shortcut
46
+ ## todo/check - assert coords has at least two x/y pairs - why? why not?
47
+ move_to( *coords[0..1] )
48
+ coords[2..-1].each_slice( 2) do |coord|
49
+ line_to( *coord )
50
+ end
51
+ self
52
+ end
53
+
54
+
55
+
56
+ def to_svg
57
+ buf = %Q{<path style="stroke: #{@stroke}; fill: #{@fill || 'none'};" }
58
+ buf << %Q{d="}
59
+ last_command = ''
60
+ @commands.each_with_index do |command,i|
61
+ buf << " " if i > 0 # add space separator
62
+
63
+ ## "optimize" - that is, do not repead command if same as before
64
+ buf << command[0] if command[0] != last_command
65
+ buf << "#{command[1]} #{command[2]}"
66
+ last_command = command[0]
67
+ end
68
+
69
+ buf << %Q{"}
70
+ buf << "/>"
71
+ buf
72
+ end
73
+ end # class Path
74
+
28
75
 
29
76
 
30
77
  def initialize( width, height, header: nil )
@@ -39,6 +86,14 @@ class Vector # holds a vector graphics image (in source)
39
86
  @shapes << Circle.new( cx, cy, r, fill: fill )
40
87
  end
41
88
 
89
+ ## note: default stroke (color) to black (#000000) for now - why? why not?
90
+ def path( stroke: '#000000', fill: nil )
91
+ path = Path.new( stroke: stroke, fill: fill )
92
+ @shapes << path
93
+
94
+ path ## note: MUST return "inner" path shape for chaining "dsl-like" methods / commands
95
+ end
96
+
42
97
 
43
98
 
44
99
  def to_image
@@ -3,7 +3,7 @@ module Pixelart
3
3
 
4
4
  MAJOR = 1
5
5
  MINOR = 2
6
- PATCH = 0
6
+ PATCH = 3
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
data/lib/pixelart.rb CHANGED
@@ -8,3 +8,5 @@ require 'pixelart/base' # aka "strict(er)" version
8
8
  # make Image, Color, Palette8bit, etc top-level
9
9
  include Pixelart
10
10
 
11
+
12
+
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: 1.2.0
4
+ version: 1.2.3
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-10-02 00:00:00.000000000 Z
11
+ date: 2022-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: chunky_png
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: csvreader
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rdoc
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -89,6 +103,7 @@ files:
89
103
  - lib/pixelart.rb
90
104
  - lib/pixelart/base.rb
91
105
  - lib/pixelart/blur.rb
106
+ - lib/pixelart/circle.rb
92
107
  - lib/pixelart/color.rb
93
108
  - lib/pixelart/composite.rb
94
109
  - lib/pixelart/gradient.rb
@@ -97,11 +112,14 @@ files:
97
112
  - lib/pixelart/misc.rb
98
113
  - lib/pixelart/palette.rb
99
114
  - lib/pixelart/pixelator.rb
115
+ - lib/pixelart/silhouette.rb
100
116
  - lib/pixelart/sketch.rb
101
117
  - lib/pixelart/spots.rb
118
+ - lib/pixelart/transparent.rb
119
+ - lib/pixelart/ukraine.rb
102
120
  - lib/pixelart/vector.rb
103
121
  - lib/pixelart/version.rb
104
- homepage: https://github.com/rubycoco/pixel
122
+ homepage: https://github.com/pixelartexchange/pixel
105
123
  licenses:
106
124
  - Public Domain
107
125
  metadata: {}