pixelart 1.3.2 → 1.3.3

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: f92122c8e9247bc55e6068de9ed5d8d4fcee830efec5878235af10b3a969da02
4
- data.tar.gz: 5823cae5dc165d280ff68925e0aaa35d1f34fb5b2df9da1e75d3cacc9aab378d
3
+ metadata.gz: 0724e3e1f83da6ef84325d79706a2f59d773eb31478f1e4d797ff582dad64a4a
4
+ data.tar.gz: 7d75ebe3aef0abb3e3d142bf787995bbcdf797416912a387601110a3547d08fe
5
5
  SHA512:
6
- metadata.gz: 3ff8f76c9cacbbbe28d5036c6c525c6bf1f9aab9c0a48d13bec657866a5a79ab85f9e604e343b0df7d29d05a1c6858e379cd562c9ae1d1fa60cd7fc5056a1cb0
7
- data.tar.gz: dfb12289285f8b9e8091e70549c1eedb1aee8c06c29b3176d51221e2e45843b43f5ae07dcb47beb05cb9070bbebb2d1ebdfbd48419843c550cd55117e74b9f09
6
+ metadata.gz: 6afe87fa92ec1de03bad71cd5f2ba298f78287b77f514a6c74cae6747c1e1d62790d722c07fb0a5d049dcf9966d4fa0a473688e71c717de534420f4746b711f2
7
+ data.tar.gz: 0b1a7cf13cdffa7410a6c0246f894d3ca5f1e3b1347fd90b9f7cbe9ed3cff4b4fc87c6704d80854b5337aa5f17e24631c28bc8188e4c6f86422e862d22949d43
data/Manifest.txt CHANGED
@@ -6,14 +6,11 @@ lib/pixelart.rb
6
6
  lib/pixelart/base.rb
7
7
  lib/pixelart/blur.rb
8
8
  lib/pixelart/circle.rb
9
- lib/pixelart/color.rb
10
9
  lib/pixelart/composite.rb
11
10
  lib/pixelart/generator.rb
12
- lib/pixelart/gradient.rb
13
11
  lib/pixelart/image.rb
14
12
  lib/pixelart/led.rb
15
13
  lib/pixelart/misc.rb
16
- lib/pixelart/palette.rb
17
14
  lib/pixelart/pixelator.rb
18
15
  lib/pixelart/sample.rb
19
16
  lib/pixelart/silhouette.rb
data/README.md CHANGED
@@ -288,3 +288,9 @@ 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
+
292
+
293
+
294
+ ## Questions? Comments?
295
+
296
+ Post them on the [D.I.Y. Punk (Pixel) Art reddit](https://old.reddit.com/r/DIYPunkArt). Thanks.
data/Rakefile CHANGED
@@ -18,6 +18,7 @@ Hoe.spec 'pixelart' do
18
18
  self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
+ ['pixelart-colors'],
21
22
  ['chunky_png'],
22
23
  ['mini_magick'],
23
24
  ['csvreader'],
data/lib/pixelart/base.rb CHANGED
@@ -1,3 +1,9 @@
1
+ ###
2
+ # base module
3
+ require 'pixelart/colors'
4
+
5
+
6
+
1
7
  ###############
2
8
  # 3rd party
3
9
  require 'chunky_png'
@@ -11,23 +17,9 @@ require 'mini_magick'
11
17
  require 'csvreader'
12
18
 
13
19
 
14
- ## stdlib
15
- require 'pp'
16
- require 'time'
17
- require 'date'
18
- require 'fileutils'
19
-
20
- require 'json'
21
- require 'yaml'
22
-
23
-
24
-
25
20
 
26
21
  ## our own code
27
22
  require 'pixelart/version' # note: let version always go first
28
- require 'pixelart/color'
29
- require 'pixelart/gradient'
30
- require 'pixelart/palette'
31
23
  require 'pixelart/image'
32
24
  require 'pixelart/composite'
33
25
 
@@ -73,21 +65,4 @@ require 'pixelart/blur'
73
65
 
74
66
 
75
67
 
76
-
77
-
78
- ##########
79
- # add some spelling convenience variants
80
- PixelArt = Pixelart
81
-
82
- module Pixelart
83
- Palette256 = Palette8Bit = Palette8bit
84
-
85
- Palette256Image = Palette8BitImage = Palette8bitImage =
86
- ImagePalette256 = ImagePalette8Bit = ImagePalette8bit
87
-
88
- CompositeImage = ImageComposite
89
- end
90
-
91
-
92
-
93
68
  puts Pixelart.banner # say hello
@@ -3,7 +3,7 @@ module Pixelart
3
3
 
4
4
  MAJOR = 1
5
5
  MINOR = 3
6
- PATCH = 2
6
+ PATCH = 3
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version
data/lib/pixelart.rb CHANGED
@@ -9,4 +9,14 @@ require 'pixelart/base' # aka "strict(er)" version
9
9
  include Pixelart
10
10
 
11
11
 
12
+ ##########
13
+ # add some spelling convenience variants
14
+
15
+
16
+ module Pixelart
17
+ Palette256Image = Palette8BitImage = Palette8bitImage =
18
+ ImagePalette256 = ImagePalette8Bit = ImagePalette8bit
19
+
20
+ CompositeImage = ImageComposite
21
+ end
12
22
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pixelart
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.3.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: 2022-05-28 00:00:00.000000000 Z
11
+ date: 2022-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pixelart-colors
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: chunky_png
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -104,14 +118,11 @@ files:
104
118
  - lib/pixelart/base.rb
105
119
  - lib/pixelart/blur.rb
106
120
  - lib/pixelart/circle.rb
107
- - lib/pixelart/color.rb
108
121
  - lib/pixelart/composite.rb
109
122
  - lib/pixelart/generator.rb
110
- - lib/pixelart/gradient.rb
111
123
  - lib/pixelart/image.rb
112
124
  - lib/pixelart/led.rb
113
125
  - lib/pixelart/misc.rb
114
- - lib/pixelart/palette.rb
115
126
  - lib/pixelart/pixelator.rb
116
127
  - lib/pixelart/sample.rb
117
128
  - lib/pixelart/silhouette.rb
@@ -1,131 +0,0 @@
1
- module Pixelart
2
-
3
-
4
- class Color
5
- TRANSPARENT = 0 # rgba( 0, 0, 0, 0)
6
- BLACK = 0xff # rgba( 0, 0, 0,255)
7
- WHITE = 0xffffffff # rgba(255,255,255,255)
8
-
9
-
10
- def self.parse( color )
11
- if color.is_a?( Integer ) ## e.g. assumes ChunkyPNG::Color.rgb() or such
12
- color ## pass through as is 1:1
13
- elsif color.is_a?( Array ) ## assume array of hsl(a) e. g. [180, 0.86, 0.88]
14
- from_hsl( *color )
15
- elsif color.is_a?( String )
16
- if color.downcase == 'transparent' ## special case for builtin colors
17
- TRANSPARENT
18
- else
19
- ## note: return an Integer !!! (not a Color class or such!!! )
20
- from_hex( color )
21
- end
22
- else
23
- raise ArgumentError, "unknown color format; cannot parse - expected rgb hex string e.g. d3d3d3"
24
- end
25
- end
26
-
27
- def self.from_hex( hex )
28
- ## Creates a color by converting it from a string in hex notation.
29
- ##
30
- ## It supports colors with (#rrggbbaa) or without (#rrggbb)
31
- ## alpha channel as well as the 3-digit short format (#rgb)
32
- ## for those without. Color strings may include
33
- ## the prefix "0x" or "#"".
34
- ChunkyPNG::Color.from_hex( hex )
35
- end
36
-
37
- def self.from_hsl( hue, saturation, lightness, alpha=255)
38
- ChunkyPNG::Color.from_hsl( hue,
39
- saturation,
40
- lightness,
41
- alpha )
42
- end
43
-
44
-
45
- def self.to_hex( color, include_alpha: true )
46
- ChunkyPNG::Color.to_hex( color, include_alpha )
47
- end
48
-
49
- def self.to_hsl( color, include_alpha: true )
50
- # Returns an array with the separate HSL components of a color.
51
- ChunkyPNG::Color.to_hsl( color, include_alpha )
52
- end
53
-
54
- def self.r( color ) ChunkyPNG::Color.r( color ); end
55
- def self.g( color ) ChunkyPNG::Color.g( color ); end
56
- def self.b( color ) ChunkyPNG::Color.b( color ); end
57
-
58
- def self.rgb( r, g, b ) ChunkyPNG::Color.rgb( r, g, b); end
59
-
60
-
61
-
62
- ## known built-in color names
63
- def self.build_names
64
- names = {
65
- '#00000000' => 'TRANSPARENT',
66
- '#000000ff' => 'BLACK',
67
- '#ffffffff' => 'WHITE',
68
- }
69
-
70
- ## auto-add grayscale 1 to 254
71
- (1..254).each do |n|
72
- hex = "#" + ('%02x' % n)*3
73
- hex << "ff" ## add alpha channel (255)
74
- names[ hex ] = "8-BIT GRAYSCALE ##{n}"
75
- end
76
-
77
- names
78
- end
79
-
80
- NAMES = build_names
81
-
82
-
83
-
84
- def self.format( color )
85
- rgb = [r(color),
86
- g(color),
87
- b(color)]
88
-
89
- # rgb in hex (string format)
90
- # note: do NOT include alpha channel for now - why? why not?
91
- hex = "#" + rgb.map{|num| '%02x' % num }.join
92
-
93
- hsl = to_hsl( color )
94
- ## get alpha channel (transparency) for hsla
95
- alpha = hsl[3]
96
-
97
-
98
- buf = ''
99
- buf << hex
100
- buf << " / "
101
- buf << "rgb("
102
- buf << "%3d " % rgb[0]
103
- buf << "%3d " % rgb[1]
104
- buf << "%3d)" % rgb[2]
105
- buf << " - "
106
- buf << "hsl("
107
- buf << "%3d° " % (hsl[0] % 360)
108
- buf << "%3d%% " % (hsl[1]*100+0.5).to_i
109
- buf << "%3d%%)" % (hsl[2]*100+0.5).to_i
110
-
111
- if alpha != 255
112
- buf << " - α(%3d%%)" % (alpha*100/255+0.5).to_i
113
- else
114
- buf << " " ## add empty for 255 (full opacity)
115
- end
116
-
117
- ## note: add alpha channel to hex
118
- alpha_hex = '%02x' % alpha
119
- name = NAMES[ hex+alpha_hex ]
120
- buf << " - #{name}" if name
121
-
122
- buf
123
- end
124
- class << self
125
- alias_method :fmt, :format
126
- end
127
-
128
- end # class Color
129
- end # module Pixelart
130
-
131
-
@@ -1,106 +0,0 @@
1
-
2
- ## inspired / helped by
3
- ## https://en.wikipedia.org/wiki/List_of_software_palettes#Color_gradient_palettes
4
- ## https://github.com/mistic100/tinygradient
5
- ## https://mistic100.github.io/tinygradient/
6
- ## https://bsouthga.dev/posts/color-gradients-with-python
7
-
8
-
9
- module Pixelart
10
-
11
- class Gradient
12
-
13
- def initialize( *stops )
14
- ## note: convert stop colors to rgb triplets e.g.
15
- ## from #ffffff to [255,255,255]
16
- ## #000000 to [0,0,0] etc.
17
- @stops = stops.map do |stop|
18
- stop = Color.parse( stop )
19
- [Color.r(stop), Color.g(stop), Color.b(stop)]
20
- end
21
- end
22
-
23
-
24
- def colors( steps )
25
- segments = @stops.size - 1
26
-
27
- ## note: gradient will include start (first)
28
- ## AND stop color (last) - stop color is NOT excluded for now!!
29
- if segments == 1
30
- start = @stops[0]
31
- stop = @stops[1]
32
-
33
- gradient = linear_gradient( start, stop, steps,
34
- include_stop: true )
35
- else
36
- steps_per_segment, mod = steps.divmod( segments )
37
- raise ArgumentError, "steps (#{steps}) must be divisible by # of segments (#{segments}); expected mod of 0 but got #{mod}" if mod != 0
38
-
39
- gradient = []
40
- segments.times do |segment|
41
- start = @stops[segment]
42
- stop = @stops[segment+1]
43
- include_stop = (segment == segments-1) ## note: only include stop if last segment!!
44
-
45
- # print " segment #{segment+1}/#{segments} #{steps_per_segment} color(s) - "
46
- # print " start: #{start.inspect} "
47
- # print include_stop ? 'include' : 'exclude'
48
- # print " stop: #{stop.inspect}"
49
- # print "\n"
50
-
51
- gradient += linear_gradient( start, stop, steps_per_segment,
52
- include_stop: include_stop )
53
- end
54
- end
55
-
56
- ## convert to color (Integer)
57
- gradient.map do |color|
58
- Color.rgb( *color )
59
- end
60
- end
61
-
62
-
63
-
64
- def interpolate( start, stop, steps, n )
65
- ## note: n - expected to start with 1,2,3,etc.
66
- color = []
67
- 3.times do |i|
68
- stepize = Float(stop[i] - start[i]) / Float(steps-1)
69
- value = stepize * n
70
- ## convert back to Integer from Float
71
- ## add 0.5 for rounding up (starting with 0.5) - why? why not?
72
- value = (value+0.5).to_i
73
- value = start[i] + value
74
-
75
- color << value
76
- end
77
- color
78
- end
79
-
80
-
81
- def linear_gradient( start, stop, steps,
82
- include_stop: true )
83
-
84
- gradient = [start] ## auto-add start color (first color in gradient)
85
-
86
- if include_stop
87
- 1.upto( steps-2 ).each do |n| ## sub two (-2), that is, start and stop color
88
- gradient << interpolate( start, stop, steps, n )
89
- end
90
- # note: use original passed in stop color (should match calculated)
91
- gradient << stop
92
- else
93
- 1.upto( steps-1 ).each do |n| ## sub one (-1), that is, start color only
94
- ## note: add one (+1) to steps because stop color gets excluded (not included)!!
95
- gradient << interpolate( start, stop, steps+1, n )
96
- end
97
- end
98
-
99
- gradient
100
- end
101
-
102
-
103
-
104
- end # class Gradient
105
- end # module Pixelart
106
-
@@ -1,72 +0,0 @@
1
- module Pixelart
2
-
3
-
4
- class Palette8bit # or use Palette256 alias?
5
-
6
-
7
- ## auto-add grayscale 0 to 255
8
- ## e.g. rgb(0,0,0)
9
- ## rgb(1,1,1)
10
- ## rgb(2,2,2)
11
- ## ...
12
- ## rgb(255,255,255)
13
- GRAYSCALE = (0..255).map { |n| Color.rgb( n, n, n ) }
14
-
15
-
16
- ## 8x32 gradient color stops
17
- ## see https://en.wikipedia.org/wiki/List_of_software_palettes#Color_gradient_palettes
18
-
19
- SEPIA_STOPS = [
20
- ['080400', '262117'],
21
- ['272218', '453E2F'],
22
- ['463F30', '645C48'],
23
- ['655D48', '837A60'],
24
-
25
- ['847A60', 'A29778'],
26
- ['A39878', 'C1B590'],
27
- ['C2B691', 'E0D2A8'],
28
- ['E1D3A9', 'FEEFBF'],
29
- ]
30
-
31
- BLUE_STOPS = [
32
- ['000000', '001F3E'],
33
- ['002040', '003F7E'],
34
- ['004080', '005FBD'],
35
- ['0060BF', '007FFD'],
36
-
37
- ['0080FF', '009FFF'],
38
- ['00A0FF', '00BFFF'],
39
- ['00C0FF', '00DFFF'],
40
- ['00E0FF', '00FEFF'],
41
- ]
42
-
43
- FALSE_STOPS = [
44
- ['FF00FF', '6400FF'],
45
- ['5F00FF', '003CFF'],
46
- ['0041FF', '00DCFF'],
47
- ['00E1FF', '00FF82'],
48
-
49
- ['00FF7D', '1EFF00'],
50
- ['23FF00', 'BEFF00'],
51
- ['C3FF00', 'FFA000'],
52
- ['FF9B00', 'FF0000'],
53
- ]
54
-
55
-
56
- def self.build_palette( gradients )
57
- colors_per_gradient, mod = 256.divmod( gradients.size )
58
- raise ArgumentError, "8bit palette - 256 must be divisible by # of gradients (#{gradients.size}; expected mod of 0 but got #{mod}" if mod != 0
59
-
60
- colors = []
61
- gradients.each do |stops|
62
- colors += Gradient.new( *stops ).colors( colors_per_gradient )
63
- end
64
- colors
65
- end
66
-
67
- SEPIA = build_palette( SEPIA_STOPS )
68
- BLUE = build_palette( BLUE_STOPS )
69
- FALSE = build_palette( FALSE_STOPS )
70
- end # class Palette8bit
71
- end # module Pixelart
72
-