stitchify 0.2.5 → 0.4.0

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
  SHA1:
3
- metadata.gz: e5895de25d1f7278da3b3f19429bc973bdc25d7b
4
- data.tar.gz: ffbae7c51bff3f8313bbc37e5b39604d5d796c75
3
+ metadata.gz: a69e46357be5a7471d4e299fdf2991ed93807852
4
+ data.tar.gz: 69ac7719b3df36c5fd33282fcadf62f7cfa97c37
5
5
  SHA512:
6
- metadata.gz: 87b63def2fbc5aa49d24af785ecf1886c46a0728f27cd2f86d72760b5e09d6bb3da8b411b53c50a0e7d360f6c66e093c5ccab173d6be27725c137b7e7a57ebac
7
- data.tar.gz: 3538d477176f23a093161495db5abfef06bd7bc86f1ac635e68ee9add3ee4a3e16ceb58a250918037f09001cebc25fb4984821fddd3e771886567fd625a7be44
6
+ metadata.gz: 8ac0ab428ea0ae7c8ea8d72bad8cac09c21f39e013cad8995eccd9b9ba94c14d82c7eaeba1cff63d23e59968d1c8850b081d9a0032d65823bfcd1d8c9874c1d1
7
+ data.tar.gz: 4231feda99f27a2e1407eba36dccc9646d8c50d10b3883220e8895cf958ba110ab42c98875d2cf9f6901f978c6504c64bfeb3f6414f2ce854809111c0633b776
@@ -21,15 +21,19 @@ class Stitchifier
21
21
  'triangle',
22
22
  'circle',
23
23
  'diamond',
24
+ 'heart',
25
+ 'star',
24
26
  'reverse_triangle',
25
27
  'left_triangle',
26
28
  'right_triangle'
27
29
  ]
28
30
 
29
31
  attr_accessor :base_pixel_arr,
32
+ :color_set,
30
33
  :dominant_colors,
31
34
  :img,
32
35
  :img_path,
36
+ :file_path,
33
37
  :num_of_colors,
34
38
  :num_of_off_colors,
35
39
  :pos_x,
@@ -38,7 +42,7 @@ class Stitchifier
38
42
  :stitch_map,
39
43
  :width
40
44
 
41
- def initialize(img_path = '', width = 50, px=10, num_of_colors = 8)
45
+ def initialize(img_path = '', width = 50, px=10, num_of_colors=8, file_path='stitchify.svg')
42
46
  # sets variables
43
47
  self.num_of_colors = num_of_colors
44
48
  set_num_colors
@@ -48,23 +52,28 @@ class Stitchifier
48
52
  self.dominant_colors = []
49
53
  self.stitch_map = []
50
54
  self.px = px
55
+ self.color_set = nil
56
+ self.file_path = file_path
51
57
 
52
58
  unless img_path.empty?
53
59
  make_img
54
- set_dominant_colors
60
+ build_color_set
55
61
  build_pixel_array
56
62
 
57
- d = DrawRasem.new(self.stitch_map, self.width, self.px)
58
- d.stitch
63
+ stitch
59
64
  end
60
65
  end
61
66
 
67
+ def stitch
68
+ d = DrawRasem.new(self.stitch_map, self.width, self.px, self.color_set, self.file_path)
69
+ d.stitch
70
+ end
71
+
62
72
  def make_img
63
73
  self.img = ImageList.new(img_path).resize_to_fit(width)
64
74
  end
65
75
 
66
76
  def set_dominant_colors
67
- color_pos = 0
68
77
  colors = black_and_white
69
78
  set_num_colors
70
79
  if self.num_of_colors > 3 && !img_path.empty?
@@ -74,13 +83,32 @@ class Stitchifier
74
83
  off_colors = build_off_color_arr(main_color)
75
84
  colors = miro_px + off_colors + colors
76
85
  end
86
+ set_px_shapes(colors)
87
+ self.dominant_colors = colors.uniq
88
+ end
89
+
90
+ def set_px_shapes(colors)
91
+ color_pos = 0
77
92
  colors.each do |px|
78
93
  if px.shape.nil?
79
94
  px.shape = FILLABLE_SHAPES[color_pos]
80
95
  color_pos = (color_pos + 1) % FILLABLE_SHAPES.length
81
96
  end
82
97
  end
83
- self.dominant_colors = colors.uniq
98
+ end
99
+
100
+ def build_color_set(req_colors = [])
101
+ if req_colors.length == 0
102
+ set_dominant_colors
103
+ self.color_set = self.dominant_colors
104
+ else
105
+ set_dominant_colors
106
+ colors = self.dominant_colors
107
+ colors.slice!(0, req_colors.length)
108
+ color_map = colors + req_colors.map{ |x| Pixelfy.from_hex(x) }
109
+ self.color_set = set_px_shapes(color_map)
110
+ end
111
+ build_pixel_array
84
112
  end
85
113
 
86
114
  def black_and_white
@@ -105,7 +133,8 @@ class Stitchifier
105
133
  end
106
134
 
107
135
  def colorize_pixels
108
- self.base_pixel_arr.each {|px| self.stitch_map << px.colorize(self.dominant_colors) }
136
+ self.stitch_map = []
137
+ self.base_pixel_arr.each {|px| self.stitch_map << px.colorize(self.color_set) }
109
138
  end
110
139
 
111
140
  def set_num_colors
@@ -1,16 +1,25 @@
1
1
  class DrawRasem
2
2
 
3
- attr_accessor :px_arr, :width, :px, :pos_x, :pos_y, :height
3
+ attr_accessor :color_set,
4
+ :file_path,
5
+ :height,
6
+ :pos_x,
7
+ :pos_y,
8
+ :px,
9
+ :px_arr,
10
+ :width
4
11
 
5
- def initialize(px_arr, width=50, px=10)
12
+ def initialize(px_arr, width=50, px=10, color_set=[], file_path='stitchify.svg')
6
13
  self.px_arr = px_arr
7
14
  self.width = width
8
15
  self.px = px
16
+ self.color_set = color_set
17
+ self.file_path = file_path
9
18
  clear_vars
10
19
  end
11
20
 
12
21
  def stitch
13
- write(build_rasem_data, file='stitchify.svg')
22
+ write(build_rasem_data, self.file_path)
14
23
  clear_vars
15
24
  end
16
25
 
@@ -30,42 +39,126 @@ class DrawRasem
30
39
  rasem_obj = self
31
40
 
32
41
  Rasem::SVGImage.new(width: 1000000000, height: 100000000) do
42
+ pos_x = rasem_obj.pos_x
43
+ pos_y = rasem_obj.pos_y
44
+ px = rasem_obj.px
45
+ a = px / 4
46
+ b = px / 2
47
+ c = px - a
48
+ d = a / 2
33
49
 
34
- for line_data in rasem_obj.grid
35
- line line_data[0], line_data[1], line_data[2], line_data[3], :stroke_width=>line_data[5]
36
- end
50
+ defs do
51
+ group(id: 'rectangle') do
52
+ rectangle pos_x, pos_y, px, px
53
+ end
37
54
 
38
- for pixel in rasem_obj.px_arr
39
- pos_x = rasem_obj.pos_x
40
- pos_y = rasem_obj.pos_y
41
- px = rasem_obj.px
42
-
43
- case pixel.shape
44
- when 'rectangle'
45
- rectangle pos_x, pos_y, px, px, fill: pixel.hex
46
- when 'x'
55
+ group(id: 'x') do
47
56
  line pos_x, pos_y, pos_x + px, pos_y + px
48
57
  line pos_x, pos_y + px, pos_x + px, pos_y
49
- when 'circle'
50
- circle (pos_x + px/2), (pos_y + px/2), px / 2 - 1, fill: pixel.hex
51
- when 'sm_rectangle'
52
- rectangle pos_x + 1, pos_y + 1, px - 2, px - 2, fill: pixel.hex
53
- when 'triangle'
54
- polygon [pos_x + px/2, pos_y + 1], [pos_x + 1, pos_y + px - 1], [pos_x + px - 1, pos_y + px - 1], fill: pixel.hex
55
- when 'diamond'
56
- polygon [pos_x + px/2, pos_y + 1], [pos_x + 1, pos_y + px/2], [pos_x + px/2, pos_y + px - 1], [pos_x + px - 1, pos_y + px/2], fill: pixel.hex
57
- when 'reverse_triangle'
58
- polygon [pos_x + px/2, pos_y + px - 1], [pos_x + 1, pos_y + 1], [pos_x + px - 1, pos_y + 1], fill: pixel.hex
59
- when 'left_triangle'
60
- polygon [pos_x + 1, pos_y + px/2], [pos_x + px - 1, pos_y + 1], [pos_x + px - 1, pos_y + px - 1], fill: pixel.hex
61
- when 'right_triangle'
62
- polygon [pos_x + px - 1, pos_y + px/2], [pos_x + 1, pos_y + 1], [pos_x + 1, pos_y + px - 1], fill: pixel.hex
63
- else
64
- rectangle pos_x, pos_y, px, px, fill: pixel.hex
65
58
  end
66
59
 
60
+ group(id: 'circle') do
61
+ circle (pos_x + b), (pos_y + b), a + d
62
+ end
63
+
64
+ group(id: 'sm_rectangle') do
65
+ rectangle pos_x + a + 1, pos_y + a + 1, b, b
66
+ end
67
+
68
+ group(id: 'triangle') do
69
+ polygon [pos_x + b, pos_y + a],
70
+ [pos_x + c, pos_y + c],
71
+ [pos_x + a, pos_y + c]
72
+ end
73
+
74
+ group(id: 'diamond') do
75
+ polygon [pos_x + b, pos_y + 1],
76
+ [pos_x + 1, pos_y + b],
77
+ [pos_x + b, pos_y + px - 1],
78
+ [pos_x + px - 1, pos_y + b]
79
+ end
80
+
81
+ group(id: 'reverse_triangle') do
82
+ polygon [pos_x + a, pos_y + a],
83
+ [pos_x + c, pos_y + a],
84
+ [pos_x + b, pos_y + c]
85
+ end
86
+
87
+ group(id: 'left_triangle') do
88
+ polygon [pos_x + a, pos_y + b],
89
+ [pos_x + c, pos_y + a],
90
+ [pos_x + c, pos_y + c]
91
+ end
92
+
93
+ group(id: 'right_triangle') do
94
+ polygon [pos_x + a, pos_y + a],
95
+ [pos_x + c, pos_y + b],
96
+ [pos_x + a, pos_y + c]
97
+ end
98
+
99
+ group(id: 'star') do
100
+ polygon [pos_x + a + 1, pos_y + 1],
101
+ [pos_x + b, pos_y + a + 1],
102
+ [pos_x + c - 1, pos_y + 1],
103
+ [pos_x + c - 1, pos_y + a + 1],
104
+ [pos_x + px - 1, pos_y + a + 1],
105
+ [pos_x + c - 1, pos_y + b],
106
+ [pos_x + px - 1, pos_y + c - 1],
107
+ [pos_x + c - 1, pos_y + c - 1],
108
+ [pos_x + c - 1, pos_y + px - 1],
109
+ [pos_x + b, pos_y + c - 1],
110
+ [pos_x + a + 1, pos_y + px - 1],
111
+ [pos_x + a + 1, pos_y + c - 1],
112
+ [pos_x + 1, pos_y + c - 1],
113
+ [pos_x + a + 1, pos_y + b],
114
+ [pos_x + 1, pos_y + a + 1],
115
+ [pos_x + a + 1, pos_y + a + 1],
116
+ [pos_x + a + 1, pos_y + 1]
117
+ end
118
+
119
+ group(id: 'heart') do
120
+ polygon [pos_x + a, pos_y + a],
121
+ [pos_x + b - d, pos_y + a],
122
+ [pos_x + b, pos_y + b - d],
123
+ [pos_x + b + d, pos_y + a],
124
+ [pos_x + c, pos_y + a],
125
+ [pos_x + c, pos_y + b],
126
+ [pos_x + b, pos_y + c],
127
+ [pos_x + a, pos_y + b]
128
+ end
129
+ end
130
+
131
+ # grid
132
+ group stroke: 'black' do
133
+ for line_data in rasem_obj.grid
134
+ line line_data[0], line_data[1], line_data[2], line_data[3], :stroke_width=>line_data[5]
135
+ end
136
+
137
+ blocks = rasem_obj.width / 10
138
+ blocks.times do |i|
139
+ text((i + 1) * 10 * px + b, c, stroke_width: 1, 'font-size': '8px', class: 'grid-numbers') { raw (i + 1) * 10 }
140
+ text(1, (i + 1) * 10 * px + px + a, stroke_width: 1, 'font-size': '8px', class: 'grid-numbers') { raw (i + 1) * 10 }
141
+ end
142
+ end
143
+
144
+ # content
145
+ for pixel in rasem_obj.px_arr
146
+ use(pixel.shape, x: rasem_obj.pos_x - px, y: rasem_obj.pos_y - px, fill: pixel.hex)
67
147
  rasem_obj.update_positions
68
148
  end
149
+
150
+ # legend
151
+ group stroke: 'black' do
152
+ legend_pos_x = (rasem_obj.width + 2) * px
153
+ legend_pos_y = 2 * px
154
+ legend_height = px * (rasem_obj.color_set.length * 2)
155
+ rectangle legend_pos_x, legend_pos_y, 10 * px, legend_height, fill: 'white'
156
+ rasem_obj.color_set.each_with_index do |pixel, index|
157
+ use(pixel.shape, x: legend_pos_x - b, y: legend_pos_y - b, fill: pixel.hex)
158
+ text(legend_pos_x + 2 * px, legend_pos_y + px + b) { raw pixel.hex }
159
+ legend_pos_y += 2 * px
160
+ end
161
+ end
69
162
  end
70
163
  end
71
164
 
@@ -39,26 +39,24 @@ class Pixelfy
39
39
  "#{HSL_OPEN_CONST} #{self.hue}, #{self.saturation}%, #{self.lightness}%, 1)"
40
40
  end
41
41
 
42
+ def name
43
+ n = ''
44
+ c = Chroma::Color.new(hsl).to_name
45
+ n = c unless c == "<unknown>"
46
+
47
+ end
48
+
42
49
  def colorize(map)
43
50
  deltae = 100000000000
44
51
  closest_px = map[0]
45
52
 
46
53
  map.each do |dom_px|
47
- hue_delta = (dom_px.hue - self.hue).abs
48
-
49
- if hue_delta < deltae
50
-
51
- deltae = hue_delta
52
- closest_px = dom_px
53
-
54
- elsif hue_delta == deltae
55
- dom_px_delta = self.get_full_delta(dom_px)
56
- current_px_delta = self.get_full_delta(closest_px)
57
- if dom_px_delta < current_px_delta
58
- deltae = hue_delta
59
- closest_px = dom_px
60
- end
61
- end
54
+ dom_px_delta = self.get_delta_e(dom_px)
55
+ current_px_delta = self.get_delta_e(closest_px)
56
+ if dom_px_delta < current_px_delta
57
+ deltae = dom_px_delta
58
+ closest_px = dom_px
59
+ end
62
60
  end
63
61
 
64
62
  self.hue = closest_px.hue
@@ -69,7 +67,7 @@ class Pixelfy
69
67
  self
70
68
  end
71
69
 
72
- def get_full_delta(px)
70
+ def get_delta_e(px)
73
71
  hue_delta = (px.hue - self.hue).abs
74
72
  sat_delta = (px.saturation - self.saturation).abs
75
73
  lit_delta = (px.lightness - self.lightness).abs
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stitchify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ellen Wondra
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-23 00:00:00.000000000 Z
11
+ date: 2020-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rasem
@@ -56,60 +56,60 @@ dependencies:
56
56
  name: chroma
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 0.2.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '='
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 0.2.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rmagick
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '2.16'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '2.16'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 12.3.1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 12.3.1
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pry
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: 0.11.3
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
111
- description: ultimate goal is to input an HTML document and output an SVG cross stitching
112
- pattern
110
+ version: 0.11.3
111
+ description: takes a .jpg image and converts it to an SVG cross stitching pattern.
112
+ You can change the colors, the width, and the number of colors used.
113
113
  email: ellenfromillinois@gmail.com
114
114
  executables: []
115
115
  extensions: []