artbase 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,149 +1,168 @@
1
-
2
-
3
-
4
- def slugify( name )
5
- name.downcase.gsub( /[^a-z0-9 ()$_-]/ ) do |_|
6
- puts " !! WARN: asciify - found (and removing) non-ascii char >#{Regexp.last_match}<"
7
- '' ## remove - use empty string
8
- end.gsub( ' ', '_')
9
- end
10
-
11
-
12
-
13
-
14
- def convert_images( collection, from: 'jpg',
15
- to: 'png' )
16
- files = Dir.glob( "./#{collection}/i/*.#{from}" )
17
- puts "==> converting #{files.size} image(s) from #{from} to #{to}"
18
-
19
- files.each_with_index do |file,i|
20
- dirname = File.dirname( file )
21
- extname = File.extname( file )
22
- basename = File.basename( file, extname )
23
-
24
- cmd = "magick convert #{dirname}/#{basename}.#{from} #{dirname}/#{basename}.#{to}"
25
-
26
- puts " [#{i+1}/#{files.size}] - #{cmd}"
27
- system( cmd )
28
-
29
- if from == 'gif'
30
- ## assume multi-images for gif
31
- ## save image-0.png to image.png
32
- path0 = "#{dirname}/#{basename}-0.#{to}"
33
- path = "#{dirname}/#{basename}.#{to}"
34
-
35
- puts " saving #{path0} to #{path}..."
36
-
37
- blob = File.open( path0, 'rb' ) { |f| f.read }
38
- File.open( path, 'wb' ) { |f| f.write( blob ) }
39
- end
40
- end
41
- end
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
- def copy_json( src, dest )
51
- uri = URI.parse( src )
52
-
53
- http = Net::HTTP.new( uri.host, uri.port )
54
-
55
- puts "[debug] GET #{uri.request_uri} uri=#{uri}"
56
-
57
- headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
58
-
59
-
60
- request = Net::HTTP::Get.new( uri.request_uri, headers )
61
- if uri.instance_of? URI::HTTPS
62
- http.use_ssl = true
63
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
64
- end
65
-
66
- response = http.request( request )
67
-
68
- if response.code == '200'
69
- puts "#{response.code} #{response.message}"
70
- puts " content_type: #{response.content_type}, content_length: #{response.content_length}"
71
-
72
- text = response.body.to_s
73
- text = text.force_encoding( Encoding::UTF_8 )
74
-
75
- data = JSON.parse( text )
76
-
77
- File.open( dest, "w:utf-8" ) do |f|
78
- f.write( JSON.pretty_generate( data ) )
79
- end
80
- else
81
- puts "!! error:"
82
- puts "#{response.code} #{response.message}"
83
- exit 1
84
- end
85
- end
86
-
87
-
88
- def copy_image( src, dest,
89
- dump_headers: false )
90
- uri = URI.parse( src )
91
-
92
- http = Net::HTTP.new( uri.host, uri.port )
93
-
94
- puts "[debug] GET #{uri.request_uri} uri=#{uri}"
95
-
96
- headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
97
-
98
- request = Net::HTTP::Get.new( uri.request_uri, headers )
99
- if uri.instance_of? URI::HTTPS
100
- http.use_ssl = true
101
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
102
- end
103
-
104
- response = http.request( request )
105
-
106
- if response.code == '200'
107
- puts "#{response.code} #{response.message}"
108
-
109
- content_type = response.content_type
110
- content_length = response.content_length
111
- puts " content_type: #{content_type}, content_length: #{content_length}"
112
-
113
- if dump_headers ## for debugging dump headers
114
- headers = response.each_header.to_h
115
- puts "htttp respone headers:"
116
- pp headers
117
- end
118
-
119
-
120
- format = if content_type =~ %r{image/jpeg}i
121
- 'jpg'
122
- elsif content_type =~ %r{image/png}i
123
- 'png'
124
- elsif content_type =~ %r{image/gif}i
125
- 'gif'
126
- else
127
- puts "!! error:"
128
- puts " unknown image format content type: >#{content_type}<"
129
- exit 1
130
- end
131
-
132
- ## make sure path exits - autocreate dirs
133
- ## make sure path exists
134
- dirname = File.dirname( "#{dest}.#{format}" )
135
- FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
136
-
137
- File.open( "#{dest}.#{format}", 'wb' ) do |f|
138
- f.write( response.body )
139
- end
140
- else
141
- puts "!! error:"
142
- puts "#{response.code} #{response.message}"
143
- exit 1
144
- end
145
- end
146
-
147
-
148
-
149
-
1
+
2
+
3
+
4
+ def slugify( name )
5
+ name.downcase.gsub( /[^a-z0-9 ()$_-]/ ) do |_|
6
+ puts " !! WARN: asciify - found (and removing) non-ascii char >#{Regexp.last_match}<"
7
+ '' ## remove - use empty string
8
+ end.gsub( ' ', '_')
9
+ end
10
+
11
+
12
+
13
+
14
+ def convert_images( collection, from: 'jpg',
15
+ to: 'png',
16
+ dir: 'i',
17
+ overwrite: true )
18
+ files = Dir.glob( "./#{collection}/#{dir}/*.#{from}" )
19
+ puts "==> converting #{files.size} image(s) from #{from} to #{to}"
20
+
21
+ files.each_with_index do |file,i|
22
+ dirname = File.dirname( file )
23
+ extname = File.extname( file )
24
+ basename = File.basename( file, extname )
25
+
26
+ ## skip convert if target / dest file already exists
27
+ next if overwrite == false && File.exist?( "#{dirname}/#{basename}.#{to}" )
28
+
29
+
30
+ cmd = "magick convert #{dirname}/#{basename}.#{from} #{dirname}/#{basename}.#{to}"
31
+
32
+ puts " [#{i+1}/#{files.size}] - #{cmd}"
33
+ system( cmd )
34
+
35
+ if from == 'gif'
36
+ ## assume multi-images for gif
37
+ ## save image-0.png to image.png
38
+ path0 = "#{dirname}/#{basename}-0.#{to}"
39
+ path = "#{dirname}/#{basename}.#{to}"
40
+
41
+ puts " saving #{path0} to #{path}..."
42
+
43
+ blob = File.open( path0, 'rb' ) { |f| f.read }
44
+ File.open( path, 'wb' ) { |f| f.write( blob ) }
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+ def copy_json( src, dest )
57
+ uri = URI.parse( src )
58
+
59
+ http = Net::HTTP.new( uri.host, uri.port )
60
+
61
+ puts "[debug] GET #{uri.request_uri} uri=#{uri}"
62
+
63
+ headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
64
+
65
+
66
+ request = Net::HTTP::Get.new( uri.request_uri, headers )
67
+ if uri.instance_of? URI::HTTPS
68
+ http.use_ssl = true
69
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
70
+ end
71
+
72
+ response = http.request( request )
73
+
74
+ if response.code == '200'
75
+ puts "#{response.code} #{response.message}"
76
+ puts " content_type: #{response.content_type}, content_length: #{response.content_length}"
77
+
78
+ text = response.body.to_s
79
+ text = text.force_encoding( Encoding::UTF_8 )
80
+
81
+ data = JSON.parse( text )
82
+
83
+ File.open( dest, "w:utf-8" ) do |f|
84
+ f.write( JSON.pretty_generate( data ) )
85
+ end
86
+ else
87
+ puts "!! error:"
88
+ puts "#{response.code} #{response.message}"
89
+ exit 1
90
+ end
91
+ end
92
+
93
+
94
+ def copy_image( src, dest,
95
+ dump_headers: false )
96
+ uri = URI.parse( src )
97
+
98
+ http = Net::HTTP.new( uri.host, uri.port )
99
+
100
+ puts "[debug] GET #{uri.request_uri} uri=#{uri}"
101
+
102
+ headers = { 'User-Agent' => "ruby v#{RUBY_VERSION}" }
103
+
104
+ request = Net::HTTP::Get.new( uri.request_uri, headers )
105
+ if uri.instance_of? URI::HTTPS
106
+ http.use_ssl = true
107
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
108
+ end
109
+
110
+ response = http.request( request )
111
+
112
+ if response.code == '200'
113
+ puts "#{response.code} #{response.message}"
114
+
115
+ content_type = response.content_type
116
+ content_length = response.content_length
117
+ puts " content_type: #{content_type}, content_length: #{content_length}"
118
+
119
+ if dump_headers ## for debugging dump headers
120
+ headers = response.each_header.to_h
121
+ puts "htttp respone headers:"
122
+ pp headers
123
+ end
124
+
125
+
126
+ format = if content_type =~ %r{image/jpeg}i
127
+ 'jpg'
128
+ elsif content_type =~ %r{image/png}i
129
+ 'png'
130
+ elsif content_type =~ %r{image/gif}i
131
+ 'gif'
132
+ elsif content_type =~ %r{image/svg}i
133
+ 'svg'
134
+ else
135
+ puts "!! error:"
136
+ puts " unknown image format content type: >#{content_type}<"
137
+ exit 1
138
+ end
139
+
140
+ ## make sure path exits - autocreate dirs
141
+ ## make sure path exists
142
+ dirname = File.dirname( "#{dest}.#{format}" )
143
+ FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname )
144
+
145
+ if format == 'svg'
146
+ ## save as text (note: assume utf-8 encoding for now)
147
+ text = response.body.to_s
148
+ text = text.force_encoding( Encoding::UTF_8 )
149
+
150
+ File.open( "#{dest}.svg", 'w:utf-8' ) do |f|
151
+ f.write( text )
152
+ end
153
+ else
154
+ ## save as binary
155
+ File.open( "#{dest}.#{format}", 'wb' ) do |f|
156
+ f.write( response.body )
157
+ end
158
+ end
159
+ else
160
+ puts "!! error:"
161
+ puts "#{response.code} #{response.message}"
162
+ exit 1
163
+ end
164
+ end
165
+
166
+
167
+
168
+
@@ -0,0 +1,31 @@
1
+ module Pixelart
2
+
3
+ class Image
4
+
5
+ ###
6
+ # add common
7
+ # pixel(ate) steps/offsets (for re/down/sampling)
8
+ DOwNSAMPLING_STEPS = {
9
+ '24x24' => {
10
+ '269x269' => Image.calc_sample_steps( 269, 24 ), # width (269px), new_width (24px)
11
+ '512x512' => Image.calc_sample_steps( 512, 24 ), # width (512px), new_width (24px)
12
+ },
13
+ '32x32' => {
14
+ '320x320' => Image.calc_sample_steps( 320, 32 ),
15
+ '512x512' => Image.calc_sample_steps( 512, 32 ),
16
+ },
17
+ '35x35' => {
18
+ '512x512' => Image.calc_sample_steps( 512, 35 ),
19
+ },
20
+ '60x60' => {
21
+ '512x512' => Image.calc_sample_steps( 512, 60 ),
22
+ },
23
+ '80x80' => {
24
+ '512x512' => Image.calc_sample_steps( 512, 80 ),
25
+ },
26
+ }
27
+
28
+ end # class Image
29
+ end # module Pixelart
30
+
31
+
data/lib/artbase/image.rb CHANGED
@@ -1,75 +1,31 @@
1
- ######################
2
- # pixelart image extensions
3
- # move upstream!!!!!
4
-
5
-
6
- module Pixelart
7
-
8
- class Image
9
- def sample( *args, **kwargs )
10
- ## note: for now always assume square image (e.g. 24x24, 32x32 and such)
11
-
12
- offsets = if kwargs[:from] && kwargs[:to]
13
- PIXEL_OFFSETS[ kwargs[:to] ][ kwargs[ :from ]]
14
- else
15
- args[0] ## assume "custom" hash of offsets
16
- end
17
-
18
- width = height = offsets.size
19
-
20
- puts " #{self.width}x#{self.height} => #{width}x#{height}"
21
-
22
-
23
- dest = Image.new( width, height )
24
-
25
- offsets.each do |offset_x, x|
26
- offsets.each do |offset_y, y|
27
- pixel = self[offset_x,offset_y]
28
-
29
- dest[x,y] = pixel
30
- end
31
- end
32
-
33
- dest
34
- end
35
- alias_method :pixelate, :sample
36
- end # class Image
37
-
38
-
39
-
40
- class ImageComposite
41
- def add_glob( glob )
42
- files = Dir.glob( glob )
43
- puts "#{files.size} file(s) found matching >#{glob}<"
44
-
45
-
46
- files = files.sort
47
- ## puts files.inspect
48
-
49
- files.each_with_index do |file,i|
50
- puts "==> [#{i+1}/#{files.size}] - #{file}"
51
- img = Image.read( file )
52
-
53
- self << img ## todo/check: use add alias - why? why not?
54
- end
55
- end
56
- end # class ImageComposite
57
- end # module Pixelart
58
-
59
-
60
- ###
61
- # add common
62
- # pixel(ate) offsets (for sampling)
63
- PIXEL_OFFSETS = {}
64
-
65
- module Pixelart
66
- class Image
67
- PIXEL_OFFSETS = ::PIXEL_OFFSETS
68
- end
69
- end # module Pixelart
70
-
71
-
72
- require_relative 'image/24x24'
73
- require_relative 'image/32x32'
74
- require_relative 'image/60x60'
75
- require_relative 'image/80x80'
1
+ ######################
2
+ # pixelart image extensions
3
+ # move upstream!!!!!
4
+
5
+
6
+ module Pixelart
7
+ class ImageComposite
8
+ def add_glob( glob )
9
+ files = Dir.glob( glob )
10
+ puts "#{files.size} file(s) found matching >#{glob}<"
11
+
12
+
13
+ files = files.sort
14
+ ## puts files.inspect
15
+
16
+ files.each_with_index do |file,i|
17
+ puts "==> [#{i+1}/#{files.size}] - #{file}"
18
+ img = Image.read( file )
19
+
20
+ self << img ## todo/check: use add alias - why? why not?
21
+ end
22
+ end
23
+ end # class ImageComposite
24
+ end # module Pixelart
25
+
26
+
27
+
28
+ require_relative 'image/sample' ## check - change to downsample/pixelate - why? why not?
29
+
30
+
31
+
@@ -0,0 +1,41 @@
1
+
2
+ ## for more ideas on retry
3
+ ## see https://github.com/ooyala/retries
4
+
5
+
6
+ ## todo/check: use a different name than retry - why? why not?
7
+ def retry_on_error( max_tries: 3, &block )
8
+ errors = []
9
+ delay = 3 ## 3 secs
10
+
11
+ begin
12
+ block.call
13
+
14
+ ## note: add more exception here (separated by comma) like
15
+ ## rescue Errno::ETIMEDOUT, Errno::ECONNREFUSED => e
16
+ rescue Net::ReadTimeout => e
17
+ ## (re)raise (use raise with arguments or such - why? why not?)
18
+ raise if errors.size >= max_tries
19
+
20
+ ## ReadTimeout, a subclass of Timeout::Error, is raised if a chunk of the response cannot be read within the read_timeout.
21
+ ## subclass of RuntimeError
22
+ ## subclass of StandardError
23
+ ## subclass of Exception
24
+ puts "!! ERROR - #{e}:"
25
+ pp e
26
+
27
+ errors << e
28
+
29
+ puts
30
+ puts "==> retrying (count=#{errors.size}, max_tries=#{max_tries}) in #{delay} sec(s)..."
31
+ sleep( delay )
32
+ retry
33
+ end
34
+
35
+ if errors.size > 0
36
+ puts " #{errors.size} retry attempt(s) on error(s):"
37
+ pp errors
38
+ end
39
+
40
+ errors
41
+ end