punkmaker 0.3.0 → 0.3.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.
@@ -8,19 +8,60 @@ module Alien ## make it a class - why? why not?
8
8
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/alien-female.png" )
9
9
 
10
10
 
11
- def self.make( color,
11
+ def self.make( color=nil,
12
+ shine: true,
12
13
  gender: 'm' )
13
- color_map = derive_color_map( color )
14
14
 
15
- punk = nil
16
- if gender == 'm'
17
- punk = BASE_M.change_colors( color_map )
18
- else
19
- punk = BASE_F.change_colors( color_map )
15
+ base = gender == 'm' ? BASE_M : BASE_F
16
+
17
+ ## note: make a copy of base
18
+ punk = Image.new( base.width, base.height )
19
+ punk.compose!( base )
20
+
21
+ if color ## change skin tone (& eyebrows)?
22
+ color_map = derive_color_map( color )
23
+ punk = punk.change_colors( color_map )
20
24
  end
25
+
26
+
27
+ if shine
28
+ shine_color = color ? derive_shine( color ) : 0xf1ffffff
29
+ if gender == 'm'
30
+ punk[9,7] = shine_color
31
+ punk[8,8] = shine_color
32
+ else
33
+ punk[9,9] = shine_color
34
+ end
35
+ end
21
36
  punk
22
37
  end
23
38
 
39
+
40
+ def self.derive_shine( color )
41
+ ## was before - reuse old formula- why? why not?
42
+ ## todo/check - check "formula" used in skintones script for humans!!!
43
+ ## lighter = Color.from_hsl(
44
+ ## (h+1)%360, # todo/check: make lighter by -1 on hue? or +1????
45
+ ## [1.0,s+0.10].min,
46
+ ## [1.0,l+0.25].min)
47
+
48
+ color = Color.from_hex( color ) if color.is_a?( String )
49
+
50
+ hsv = Color.to_hsv( color )
51
+ # pp hsv
52
+
53
+ h, s, v = hsv
54
+ h = h % 360 # make always positive (might be -50 or such)
55
+ ## pp [h,s,v]
56
+
57
+ ## add extra saturation if v(alue) / brightness is max 1.0 - why? why not?
58
+ sdiff = v >= 0.99 ? 0.35 : 0.25
59
+
60
+ lighter = Color.from_hsv( h, [0.0, s-sdiff].max, [v+0.1,1.0].min )
61
+ lighter
62
+ end
63
+
64
+
24
65
 
25
66
  def self.derive_color_map( color )
26
67
 
@@ -28,7 +69,7 @@ def self.derive_color_map( color )
28
69
  # 125 pixels #c8fbfb / rgb(200 251 251) - hsl(180° 86% 88%) - base (use as base)
29
70
  # 6 pixels #9be0e0 / rgb(155 224 224) - hsl(180° 53% 74%) - darker
30
71
  # 2 pixels #75bdbd / rgb(117 189 189) - hsl(180° 35% 60%) - darkest
31
- color = Color.parse( color ) if color.is_a?( String )
72
+ color = Color.from_hex( color ) if color.is_a?( String )
32
73
  base = color
33
74
 
34
75
  hsl = Color.to_hsl( color )
@@ -38,12 +79,6 @@ h, s, l = hsl
38
79
  h = h % 360 # make always positive (might be -50 or such)
39
80
  pp [h,s,l]
40
81
 
41
- ## todo/check - check "formula" used in skintones script for humans!!!
42
- lighter = Color.from_hsl(
43
- (h+1)%360, # todo/check: make lighter by -1 on hue? or +1????
44
- [1.0,s+0.10].min,
45
- [1.0,l+0.25].min)
46
-
47
82
 
48
83
  darker = Color.from_hsl(
49
84
  h,
@@ -58,7 +93,6 @@ darkest = Color.from_hsl(
58
93
 
59
94
  color_map = {
60
95
  '#c8fbfb' => base,
61
- '#f1ffff' => lighter,
62
96
  '#9be0e0' => darker,
63
97
  '#75bdbd' => darkest,
64
98
  }
data/lib/punkmaker/ape.rb CHANGED
@@ -6,21 +6,24 @@ module Ape ## make it a class - why? why not?
6
6
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/ape-male.png" )
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/ape-female.png" )
8
8
 
9
- def self.make( color,
9
+ def self.make( color=nil,
10
10
  gender: 'm' )
11
- color_map = derive_color_map( color )
12
-
13
- punk = nil
14
- if gender == 'm'
15
- punk = BASE_M.change_colors( color_map )
16
- else
17
- punk = BASE_F.change_colors( color_map )
18
- end
19
- punk
20
- end
11
+ base = gender == 'm' ? BASE_M : BASE_F
12
+
13
+ ## note: make a copy of base
14
+ punk = Image.new( base.width, base.height )
15
+ punk.compose!( base )
16
+
17
+ if color
18
+ color_map = derive_color_map( color )
19
+ punk = punk.change_colors( color_map )
20
+ end
21
+
22
+ punk
23
+ end
21
24
 
22
25
  def self.derive_color_map( color )
23
- color = Color.parse( color ) if color.is_a?( String )
26
+ color = Color.from_hex( color ) if color.is_a?( String )
24
27
 
25
28
  darkest = color
26
29
 
@@ -0,0 +1,60 @@
1
+
2
+ class ColorBundle
3
+
4
+ def self.read( *paths )
5
+ recs = []
6
+ paths.each do |path|
7
+ recs += read_csv( path )
8
+ end
9
+ new( recs )
10
+ end
11
+
12
+ def self.normalize_key( str )
13
+ ## remove all non-alphanum chars (a-z,0-9)
14
+ str.downcase.gsub(/[^a-z0-9]/, '').strip
15
+ end
16
+ def normalize_key( str ) self.class.normalize_key( str ); end
17
+
18
+
19
+ def initialize( recs )
20
+ @recs = recs
21
+ @colors_by_key = _build_colors_by_key( @recs )
22
+ end
23
+
24
+ def records() @recs; end
25
+
26
+ def find_by( name: )
27
+ key = normalize_key( name ) ## normalize q(uery) string/symbol
28
+ @colors_by_key[ key ]
29
+ end
30
+
31
+ def _find( name ) find_by( name: name ); end
32
+ alias_method :[], :_find
33
+
34
+
35
+ ######
36
+ ## helpers
37
+ def _build_colors_by_key( recs )
38
+ h = {}
39
+ recs.each_with_index do |rec|
40
+
41
+ color = Color.from_hex( rec['color'] )
42
+ names = (rec['names'] || '').split( '|' )
43
+
44
+ names.each do |name|
45
+ key = normalize_key( name )
46
+
47
+ if h[ key ]
48
+ puts "!!! ERROR - color name is not unique:"
49
+ pp rec
50
+ puts "duplicate:"
51
+ pp h[key]
52
+ exit 1
53
+ end
54
+ h[ key ] = color
55
+ end
56
+ end
57
+ h
58
+ end
59
+
60
+ end # class ColorBundle
@@ -6,21 +6,25 @@ module Demon ## make it a class - why? why not?
6
6
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/demon-male.png" )
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/demon-female.png" )
8
8
 
9
- def self.make( color,
9
+ def self.make( color=nil,
10
10
  gender: 'm' )
11
- color_map = derive_color_map( color )
12
-
13
- punk = nil
14
- if gender == 'm'
15
- punk = BASE_M.change_colors( color_map )
16
- else
17
- punk = BASE_F.change_colors( color_map )
18
- end
19
- punk
11
+ base = gender == 'm' ? BASE_M : BASE_F
12
+
13
+ ## note: make a copy of base
14
+ punk = Image.new( base.width, base.height )
15
+ punk.compose!( base )
16
+
17
+ if color
18
+ color_map = derive_color_map( color )
19
+ punk = punk.change_colors( color_map )
20
+ end
21
+
22
+ punk
23
+
20
24
  end
21
25
 
22
26
  def self.derive_color_map( color )
23
- color = Color.parse( color ) if color.is_a?( String )
27
+ color = Color.from_hex( color ) if color.is_a?( String )
24
28
 
25
29
  # 134 pixels #850008 / rgb(133 0 8) - hsl(356° 100% 26%) - base
26
30
  # 2 pixels #630006 / rgb( 99 0 6) - hsl(356° 100% 19%) - darker
@@ -8,47 +8,95 @@ module Human ## make it a class - why? why not?
8
8
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/human-female4.png" )
9
9
 
10
10
 
11
- def self.make( color,
11
+
12
+ def self.parse_skintone( color ) ## lookup skintone by name or rgb(a) hex string or integer "true color"
13
+ if color.is_a?( String )
14
+ Skintone[ color ] || Color.from_hex( color )
15
+ else ## assume color is integer - assert - why? why not?
16
+ color
17
+ end
18
+ end
19
+
20
+ def self.parse_eye_color( color )
21
+ if color.is_a?( String )
22
+ Color.from_hex( color )
23
+ else
24
+ color
25
+ end
26
+ end
27
+
28
+
29
+
30
+ def self.make( color=nil,
31
+ shine: true,
12
32
  eye_color: nil,
13
33
  gender: 'm' )
14
- color_map = derive_color_map( color )
15
-
16
- eye_color = Color.parse( eye_color ) if eye_color && eye_color.is_a?( String )
17
-
18
- punk = nil
19
- if gender == 'm'
20
- punk = BASE_M.change_colors( color_map )
21
- punk[10,12] = Color::WHITE # left eye dark-ish pixel to white
22
- punk[15,12] = Color::WHITE # right eye ---
23
- if eye_color
24
- punk[9,12] = eye_color
25
- punk[14,12] = eye_color
26
- end
27
- else ## assume 'f'
28
- ## for female - change lips to all black (like in male for now) - why? why not?
29
- color_map[ '#711010' ] = '#000000'
30
- punk = BASE_F.change_colors( color_map )
31
- punk[10,13] = Color::WHITE # left eye dark-ish pixel to white
32
- punk[15,13] = Color::WHITE # right eye ---
33
- if eye_color
34
- punk[9,13] = eye_color
35
- punk[14,13] = eye_color
36
- end
34
+
35
+ base = gender == 'm' ? BASE_M : BASE_F
36
+
37
+ ## note: make a copy of base
38
+ punk = Image.new( base.width, base.height )
39
+ punk.compose!( base )
40
+
41
+
42
+ skintone = color ? parse_skintone( color ) : nil
43
+ if skintone ## change skin tone (& eyebrows)?
44
+ color_map = derive_color_map( skintone )
45
+ punk = punk.change_colors( color_map )
46
+ end
47
+
48
+ if eye_color ## change eye color?
49
+ eye_color = parse_eye_color( eye_color )
50
+ if gender == 'm'
51
+ punk[9,12] = eye_color
52
+ punk[14,12] = eye_color
53
+ else
54
+ punk[9,13] = eye_color
55
+ punk[14,13] = eye_color
56
+ end
57
+ end
58
+
59
+ if shine ## add shine?
60
+ # note: default shine color is white
61
+ shine_color = skintone ? derive_shine( skintone ) : 0xffffffff
62
+ if gender == 'm'
63
+ punk[9,7] = shine_color
64
+ punk[8,8] = shine_color
65
+ else
66
+ punk[9,9] = shine_color
67
+ end
37
68
  end
38
69
 
39
70
  punk
40
71
  end
41
72
 
42
73
 
74
+ def self.derive_shine( color )
75
+ color = Color.from_hex( color ) if color.is_a?( String )
76
+
77
+ hsv = Color.to_hsv( color )
78
+ # pp hsv
79
+
80
+ h, s, v = hsv
81
+ h = h % 360 # make always positive (might be -50 or such)
82
+ ## pp [h,s,v]
83
+
84
+ ## add extra saturation if v(alue) / brightness is max 1.0 - why? why not?
85
+ sdiff = v >= 0.99 ? 0.25 : 0.15
86
+
87
+ lighter = Color.from_hsv( h, [0.0, s-sdiff].max, [v+0.1,1.0].min )
88
+ lighter
89
+ end
90
+
91
+
43
92
  ##
44
93
  ## todo/check:
45
94
  ## add a derive_colors or dervice_skintones method - why? why not?
46
95
  ## - change to name skintone_palette - why? why not?
47
96
  ## def self.derive_skintone_colors( color or base ) ???
48
97
 
49
-
50
98
  def self.derive_color_map( color )
51
- color = Color.parse( color ) if color.is_a?( String )
99
+ color = Color.from_hex( color ) if color.is_a?( String )
52
100
 
53
101
  base = color
54
102
 
@@ -59,28 +107,16 @@ module Human ## make it a class - why? why not?
59
107
  h = h % 360 # make always positive (might be -50 or such)
60
108
  pp [h,s,l]
61
109
 
62
- darker = Color.from_hsl(
63
- h,
64
- [0.0, s-0.05].max,
65
- [0.14, l-0.1].max)
66
-
67
110
  ## sub one degree on hue on color wheel (plus +10% on lightness??)
68
- darkest = Color.from_hsl(
69
- (h-1) % 360,
111
+ ## darker
112
+ eyebrows = Color.from_hsl(
113
+ h,
70
114
  s,
71
115
  [0.05, l-0.1].max)
72
116
 
73
-
74
- lighter = Color.from_hsl(
75
- (h+1) % 360,
76
- s,
77
- [1.0, l+0.1].min)
78
-
79
117
  color_map = {
80
118
  '#ead9d9' => base,
81
- '#ffffff' => lighter,
82
- '#a58d8d' => darkest,
83
- '#c9b2b2' => darker
119
+ '#a58d8d' => eyebrows,
84
120
  }
85
121
  color_map
86
122
  end
@@ -7,32 +7,37 @@ module Punk
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/mummy-female.png" )
8
8
 
9
9
 
10
- def self.make( color,
10
+ def self.make( color=nil,
11
11
  eye_color: nil,
12
12
  gender: 'm' )
13
- color_map = derive_color_map( color )
13
+ base = gender == 'm' ? BASE_M : BASE_F
14
+
15
+ ## note: make a copy of base
16
+ punk = Image.new( base.width, base.height )
17
+ punk.compose!( base )
18
+
19
+ if color
20
+ color_map = derive_color_map( color )
21
+ punk = punk.change_colors( color_map )
22
+ end
14
23
 
15
- eye_color = Color.parse( eye_color ) if eye_color && eye_color.is_a?( String )
24
+ if eye_color
25
+ eye_color = Color.from_hex( eye_color ) if eye_color.is_a?( String )
16
26
 
17
- punk = nil
18
27
  if gender == 'm'
19
- punk = BASE_M.change_colors( color_map )
20
- if eye_color
21
28
  punk[9,12] = eye_color
22
29
  punk[14,12] = eye_color
23
- end
24
30
  else ## assume 'f'
25
- punk = BASE_F.change_colors( color_map )
26
- if eye_color
27
31
  punk[10,13] = eye_color ## note: eye pos +1 pix!!
28
32
  punk[14,13] = eye_color
29
- end
30
33
  end
31
- punk
32
34
  end
35
+ punk
36
+ end
37
+
33
38
 
34
39
  def self.derive_color_map( color )
35
- color = Color.parse( color ) if color.is_a?( String )
40
+ color = Color.from_hex( color ) if color.is_a?( String )
36
41
 
37
42
  # 385 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - α( 0%) - TRANSPARENT
38
43
  # 52 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - BLACK
data/lib/punkmaker/orc.rb CHANGED
@@ -6,21 +6,24 @@ module Orc ## make it a class - why? why not?
6
6
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/orc-male.png" )
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/orc-female.png" )
8
8
 
9
- def self.make( color,
9
+ def self.make( color=nil,
10
10
  gender: 'm' )
11
- color_map = derive_color_map( color )
12
-
13
- punk = nil
14
- if gender == 'm'
15
- punk = BASE_M.change_colors( color_map )
16
- else
17
- punk = BASE_F.change_colors( color_map )
18
- end
19
- punk
11
+ base = gender == 'm' ? BASE_M : BASE_F
12
+
13
+ ## note: make a copy of base
14
+ punk = Image.new( base.width, base.height )
15
+ punk.compose!( base )
16
+
17
+ if color
18
+ color_map = derive_color_map( color )
19
+ punk = punk.change_colors( color_map )
20
+ end
21
+
22
+ punk
20
23
  end
21
24
 
22
25
  def self.derive_color_map( color )
23
- color = Color.parse( color ) if color.is_a?( String )
26
+ color = Color.from_hex( color ) if color.is_a?( String )
24
27
 
25
28
  # 380 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - α( 0%) - TRANSPARENT
26
29
  # 63 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - BLACK
@@ -6,21 +6,24 @@ module Robot ## make it a class - why? why not?
6
6
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/robot-male.png" )
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/robot-female.png" )
8
8
 
9
- def self.make( color,
9
+ def self.make( color=nil,
10
10
  gender: 'm' )
11
- color_map = derive_color_map( color )
12
-
13
- punk = nil
14
- if gender == 'm'
15
- punk = BASE_M.change_colors( color_map )
16
- else
17
- punk = BASE_F.change_colors( color_map )
18
- end
19
- punk
11
+ base = gender == 'm' ? BASE_M : BASE_F
12
+
13
+ ## note: make a copy of base
14
+ punk = Image.new( base.width, base.height )
15
+ punk.compose!( base )
16
+
17
+ if color
18
+ color_map = derive_color_map( color )
19
+ punk = punk.change_colors( color_map )
20
+ end
21
+
22
+ punk
20
23
  end
21
24
 
22
25
  def self.derive_color_map( color )
23
- color = Color.parse( color ) if color.is_a?( String )
26
+ color = Color.from_hex( color ) if color.is_a?( String )
24
27
 
25
28
  # 384 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - α( 0%) - TRANSPARENT
26
29
  # 74 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - BLACK
@@ -5,21 +5,24 @@ module Skeleton ## make it a class - why? why not?
5
5
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/skeleton-male.png" )
6
6
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/skeleton-female.png" )
7
7
 
8
- def self.make( color,
8
+ def self.make( color=nil,
9
9
  gender: 'm' )
10
- color_map = derive_color_map( color )
11
-
12
- punk = nil
13
- if gender == 'm'
14
- punk = BASE_M.change_colors( color_map )
15
- else
16
- punk = BASE_F.change_colors( color_map )
17
- end
18
- punk
10
+ base = gender == 'm' ? BASE_M : BASE_F
11
+
12
+ ## note: make a copy of base
13
+ punk = Image.new( base.width, base.height )
14
+ punk.compose!( base )
15
+
16
+ if color
17
+ color_map = derive_color_map( color )
18
+ punk = punk.change_colors( color_map )
19
+ end
20
+
21
+ punk
19
22
  end
20
23
 
21
24
  def self.derive_color_map( color )
22
- color = Color.parse( color ) if color.is_a?( String )
25
+ color = Color.from_hex( color ) if color.is_a?( String )
23
26
 
24
27
  # 122 pixels #e0e0e0 / rgb(224 224 224) - hsl( 0° 0% 88%) - 8-BIT GRAYSCALE #224
25
28
 
@@ -0,0 +1,16 @@
1
+
2
+ module Punk
3
+ module Skintone
4
+
5
+ def self.bundle
6
+ @bundle ||= ColorBundle.read(
7
+ './config/skintone/ye_olde_punks.csv',
8
+ './config/skintone/color_me_human.csv',
9
+ './config/skintone/dr_ellis_monk.csv',
10
+ './config/skintone/punks_not_dead.csv' )
11
+ end
12
+
13
+ def self.[]( name ) bundle.find_by( name: name ); end
14
+ end # module Skintone
15
+ end # module Punk
16
+
@@ -6,21 +6,24 @@ module Vampire ## make it a class - why? why not?
6
6
  BASE_M = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/vampire-male.png" )
7
7
  BASE_F = Image.read( "#{Pixelart::Module::Punkmaker.root}/config/vampire-female.png" )
8
8
 
9
- def self.make( color,
9
+ def self.make( color=nil,
10
10
  gender: 'm' )
11
- color_map = derive_color_map( color )
12
-
13
- punk = nil
14
- if gender == 'm'
15
- punk = BASE_M.change_colors( color_map )
16
- else
17
- punk = BASE_F.change_colors( color_map )
18
- end
19
- punk
11
+ base = gender == 'm' ? BASE_M : BASE_F
12
+
13
+ ## note: make a copy of base
14
+ punk = Image.new( base.width, base.height )
15
+ punk.compose!( base )
16
+
17
+ if color
18
+ color_map = derive_color_map( color )
19
+ punk = punk.change_colors( color_map )
20
+ end
21
+
22
+ punk
20
23
  end
21
24
 
22
25
  def self.derive_color_map( color )
23
- color = Color.parse( color ) if color.is_a?( String )
26
+ color = Color.from_hex( color ) if color.is_a?( String )
24
27
 
25
28
  # 366 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - α( 0%) - TRANSPARENT
26
29
  # 67 pixels #000000 / rgb( 0 0 0) - hsl( 0° 0% 0%) - hsv( 0° 0% 0%) - BLACK
@@ -3,7 +3,7 @@ module Pixelart
3
3
  module Punkmaker
4
4
  MAJOR = 0
5
5
  MINOR = 3
6
- PATCH = 0
6
+ PATCH = 2
7
7
  VERSION = [MAJOR,MINOR,PATCH].join('.')
8
8
 
9
9
  def self.version