bitgen 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1 -0
  3. data/README.md +268 -1
  4. data/Rakefile +1 -1
  5. data/lib/bitgen.rb +123 -1
  6. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9d23acf3d75011e1eff3f5590cea308f609062716dce4f36fe9a84e16730b34
4
- data.tar.gz: 7ef652cb8f0ed2657d9690b730c063792f7dc901bd6ba63dd2772dae90c4988d
3
+ metadata.gz: 8d2da11669caadb65ebcb6af3a302c732af8b015b30c6c6ef8dc7d19db553b4d
4
+ data.tar.gz: cac6c0f92e52cb2e8dda34d2d29e1f114bd4109704d1b55404145d4b9c4be318
5
5
  SHA512:
6
- metadata.gz: d710bbb59d44b5bfb3f69b99d7efe0052b6d732b5baa145059e275ff1e43cbf138b6f8786e491829c9165c889d28c6dc98bc32d0a8a67032f46c543c9b42097f
7
- data.tar.gz: 2997033f71ceba39840ef40b5a1bd84dfbedd8c9362903ab171d131ff2fc99aa50ff0b93f11c3db147a7192b821ea03cd206689308ccb41cd62cfaa42606a349
6
+ metadata.gz: a43a312e44c8a928b41d455ea68e42e86fb24a74ae2ca8bb52f559c93a1039379c075bbd823e059a264b9d463e407abd1ce1eae35fb55cbcad0f7ce7aa2bc09a
7
+ data.tar.gz: d40be4d2466d90db4975550c8c4330884c72d6bf6a3d91d9265a6f094b30e8e55eb39755a524d69d729d6782515c14abfe2a3fee5feef2041c4ecc2ef1865c21
data/CHANGELOG.md CHANGED
@@ -1,3 +1,4 @@
1
+ ### 0.1.0 / 2023-07-30
1
2
  ### 0.0.1 / 2023-07-30
2
3
 
3
4
  * Everything is new. First release
data/README.md CHANGED
@@ -12,9 +12,276 @@ bitgen - bitcoin (inscription) generative image machinery incl gen-brc721 & co
12
12
 
13
13
  ## Usage
14
14
 
15
- To be done
15
+ ### Generative BRC-721 (Gen BRC-721 or GBRC-721)
16
16
 
17
+ (historic) ordinal (bitcoin) protocol by [Jerry Fanelli](https://github.com/jerryfane) proposed / published in mid-May 2023
17
18
 
19
+ - Generative BRC-721 Proposol - <https://github.com/jerryfane/generative-brc-721>
20
+ - Analytics (Dune) Dashboard - <https://dune.com/j543/generative-brc-721>
21
+
22
+
23
+ note: Gen BRC-721 is ded. Jerry Fanelli proposed BRC-69 as
24
+ the official successor in July 2023
25
+ BUT yes, [Ordgen / ORC-721](https://github.com/ordbase/generative-orc-721) may be the better (generative) alternative protocol / winner.
26
+
27
+
28
+ Let's try some (historic) Gen BRC-721 collections...
29
+
30
+
31
+ ### Collection №1 - 1000 Ordibots (32x32px)
32
+
33
+ _The world's first gen-brc-721_
34
+
35
+ Find the deploy text @ [inscription no 8326719](https://ordinals.com/inscription/b7205d40f3b1b1486567f0d6e53ff2812983db4c03ad7d3606812cd150c64802i0) - May 21, 2023 by Jerry Fanelli.
36
+
37
+
38
+ Let's generate some ulta-rare never-before-seen (do-it-yourself) ordibots.
39
+
40
+ ``` ruby
41
+ require 'bitgen'
42
+
43
+ ## step 1: read in the deploy text (incl the base64-encoded generative images)
44
+ gen = Bitgen::Generator.read( './ordibots.json' )
45
+
46
+
47
+ ## step 2: generate your images
48
+ bot = gen.generate( accessories: 'antenna',
49
+ body: 'gold-oval',
50
+ belly: 'chess',
51
+ face: 'happy',
52
+ )
53
+
54
+ bot.save( "./bot1.png" )
55
+ bot.zoom( 4 ).save( "./bot1@4x.png" )
56
+
57
+
58
+ bot = gen.generate( background: 'bitcoin-orange',
59
+ accessories: 'rainbow',
60
+ body: 'standard-square',
61
+ belly: 'empty',
62
+ face: 'unimpressed'
63
+ )
64
+
65
+ bot.save( "./bot2.png" )
66
+ bot.zoom( 4 ).save( "./bot2@4x.png" )
67
+
68
+
69
+ bot = gen.generate( background: 'bitcoin-orange',
70
+ accessories: 'rainbow',
71
+ body: 'black-and-white-triangular',
72
+ belly: 'square',
73
+ face: 'happy'
74
+ )
75
+
76
+ bot.save( "./bot3.png" )
77
+ bot.zoom( 4 ).save( "./bot3@4x.png" )
78
+ ```
79
+
80
+ resulting in:
81
+
82
+ ![](i/bot1.png)
83
+ ![](i/bot2.png)
84
+ ![](i/bot3.png)
85
+
86
+ in 4x:
87
+
88
+ ![](i/bot1@4x.png)
89
+ ![](i/bot2@4x.png)
90
+ ![](i/bot3@4x.png)
91
+
92
+
93
+ If you wonder what categories and names can I use?
94
+ Print the cheatsheet returned by `Catalog#cheat`.
95
+
96
+
97
+ ``` ruby
98
+ catalog = Bitgen::Catalog.read( './ordibots.json' )
99
+ puts catalog.cheat
100
+ ```
101
+
102
+ resulting in:
103
+
104
+ ```
105
+ 0 - background (4)
106
+ 0 - blue
107
+ 1 - bitcoin-orange
108
+ 2 - brown
109
+ 3 - purple
110
+ 1 - accessories (3)
111
+ 0 - antenna
112
+ 1 - none
113
+ 2 - rainbow
114
+ 2 - face (7)
115
+ 0 - happy
116
+ 1 - neutral
117
+ 2 - surprised
118
+ 3 - unimpressed
119
+ 4 - angry
120
+ 5 - bored-green
121
+ 6 - bored-red
122
+ 3 - body (9)
123
+ 0 - standard-triangular
124
+ 1 - standard-square
125
+ 2 - standard-oval
126
+ 3 - gold-oval
127
+ 4 - black-and-white-square
128
+ 5 - black-and-white-oval
129
+ 6 - black-and-white-triangular
130
+ 7 - gold-square
131
+ 8 - gold-triangular
132
+ 4 - belly (3)
133
+ 0 - empty
134
+ 1 - chess
135
+ 2 - square
136
+ ```
137
+
138
+ Now if you wonder what do these look in pixels?
139
+ Export all images (in 1x and 8x) using `Catalog#export` for browsing
140
+ using your local image viewer / file explorer.
141
+
142
+ ``` ruby
143
+ catalog = Bitgen::Catalog.read( './ordibots.json' )
144
+ catalog.export
145
+ ```
146
+
147
+ resulting in:
148
+
149
+ ```
150
+ /ordibots
151
+ +---0_background
152
+ | 0_blue.png
153
+ | 0_blue@8x.png
154
+ | 1_bitcoin-orange.png
155
+ | 1_bitcoin-orange@8x.png
156
+ | 2_brown.png
157
+ | 2_brown@8x.png
158
+ | 3_purple.png
159
+ | 3_purple@8x.png
160
+ |
161
+ +---1_accessories
162
+ | 0_antenna.png
163
+ | 0_antenna@8x.png
164
+ | 1_none.png
165
+ | 1_none@8x.png
166
+ | 2_rainbow.png
167
+ | 2_rainbow@8x.png
168
+ |
169
+ +---2_face
170
+ | 0_happy.png
171
+ | 0_happy@8x.png
172
+ | 1_neutral.png
173
+ | 1_neutral@8x.png
174
+ | 2_surprised.png
175
+ | 2_surprised@8x.png
176
+ | 3_unimpressed.png
177
+ | 3_unimpressed@8x.png
178
+ | 4_angry.png
179
+ | 4_angry@8x.png
180
+ | 5_bored-green.png
181
+ | 5_bored-green@8x.png
182
+ | 6_bored-red.png
183
+ | 6_bored-red@8x.png
184
+ |
185
+ +---3_body
186
+ | 0_standard-triangular.png
187
+ | 0_standard-triangular@8x.png
188
+ | 1_standard-square.png
189
+ | 1_standard-square@8x.png
190
+ | 2_standard-oval.png
191
+ | 2_standard-oval@8x.png
192
+ | 3_gold-oval.png
193
+ | 3_gold-oval@8x.png
194
+ | 4_black-and-white-square.png
195
+ | 4_black-and-white-square@8x.png
196
+ | 5_black-and-white-oval.png
197
+ | 5_black-and-white-oval@8x.png
198
+ | 6_black-and-white-triangular.png
199
+ | 6_black-and-white-triangular@8x.png
200
+ | 7_gold-square.png
201
+ | 7_gold-square@8x.png
202
+ | 8_gold-triangular.png
203
+ | 8_gold-triangular@8x.png
204
+ |
205
+ \---4_belly
206
+ 0_empty.png
207
+ 0_empty@8x.png
208
+ 1_chess.png
209
+ 1_chess@8x.png
210
+ 2_square.png
211
+ 2_square@8x.png
212
+ ```
213
+
214
+
215
+
216
+ ### Collection №2 - 20 000 Blooming Flower (80x80px)
217
+
218
+ Find the deploy text @ [inscription no 17707699](https://ordinals.com/inscription/1a1427e31c91566fe7fb47d7f5c1b2130bea31219a08e1de794d45512319ee61i0) - July 17, 2023.
219
+
220
+
221
+ Let's generate some ulta-rare never-before-seen (do-it-yourself) blooming flowers.
222
+
223
+ ``` ruby
224
+ require 'bitgen'
225
+
226
+ ## step 1: read in the deploy text (incl the base64-encoded generative images)
227
+ gen = Bitgen::Generator.read( './blooming-flower.json' )
228
+
229
+ ## step 2: generate your images
230
+ flower = gen.generate( background: 'new-moon',
231
+ window: 'simple-yellow',
232
+ table: 'metal',
233
+ flowerpot: 'ceramics-red',
234
+ rose: 'bud-red',
235
+ )
236
+
237
+ flower.save( "./flower1.png" )
238
+ flower.zoom( 4 ).save( "./flower1@4x.png" )
239
+
240
+
241
+ flower = gen.generate( background: 'autumn',
242
+ window: 'sliding-yellow',
243
+ table: 'wood',
244
+ flowerpot: 'ceramics-blue',
245
+ rose: 'bud-white',
246
+ )
247
+
248
+ flower.save( "./flower2.png" )
249
+ flower.zoom( 4 ).save( "./flower2@4x.png" )
250
+
251
+
252
+ flower = gen.generate( flowerpot: 'ceramics-red',
253
+ rose: 'bud-red',
254
+ )
255
+
256
+ flower.save( "./flower1a.png" )
257
+ flower.zoom( 4 ).save( "./flower1a@4x.png" )
258
+
259
+
260
+ flower = gen.generate( flowerpot: 'ceramics-blue',
261
+ rose: 'bud-white',
262
+ )
263
+
264
+ flower.save( "./flower2a.png" )
265
+ flower.zoom( 4 ).save( "./flower2a@4x.png" )
266
+ ```
267
+
268
+ resulting in:
269
+
270
+ ![](i/flower1.png)
271
+ ![](i/flower2.png)
272
+ ![](i/flower1a.png)
273
+ ![](i/flower2a.png)
274
+
275
+ in 4x:
276
+
277
+ ![](i/flower1@4x.png)
278
+ ![](i/flower2@4x.png)
279
+ ![](i/flower1a@4x.png)
280
+ ![](i/flower2a@4x.png)
281
+
282
+
283
+
284
+ That's it for now.
18
285
 
19
286
 
20
287
 
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'hoe'
3
3
 
4
4
  Hoe.spec 'bitgen' do
5
5
 
6
- self.version = '0.0.1' ## Pixelart::Module::Bitgen::VERSION
6
+ self.version = '0.1.0' ## Pixelart::Module::Bitgen::VERSION
7
7
 
8
8
 
9
9
  self.summary = "bitgen - bitcoin generative (inscription) image machinery incl. gen-brc721 & co"
data/lib/bitgen.rb CHANGED
@@ -1,2 +1,124 @@
1
+ require 'pixelart'
2
+
3
+
4
+ module Bitgen
5
+
6
+ class Catalog ## change/rename to Spritesheet / Atlas / Deploy or such - why? why not?
7
+ def self.read( path )
8
+ data = read_json( path )
9
+ # pp data
10
+
11
+ meta = {
12
+ 'slug' => data['slug'],
13
+ 'name' => data['name'],
14
+ 'dim' => data['dim']
15
+ }
16
+
17
+ attributes = {}
18
+ data['traits'].each do |category_name, h|
19
+ puts "==> #{category_name} - #{h.size} record(s)..."
20
+
21
+ h.each_with_index do |(name, h), i|
22
+ puts " #{i} - #{name} (#{h['name']}):"
23
+
24
+ img = Image.parse_base64( h['base64'] )
25
+
26
+ cat = attributes[ category_name ] ||= {}
27
+ cat[ name ] = img
28
+ end
29
+ end
30
+
31
+
32
+ new( meta: meta,
33
+ attributes: attributes )
34
+ end
35
+
36
+ def initialize( meta: {},
37
+ attributes: {} )
38
+ @meta = meta
39
+ @attributes = attributes
40
+ end
41
+
42
+ def name() @meta['name']; end
43
+ def slug() @meta['slug']; end
44
+
45
+ def dim() @meta['dim']; end
46
+ def width() @meta['dim'] ? @meta['dim'][0] : nil; end
47
+ def height() @meta['dim'] ? @meta['dim'][1] : nil; end
48
+
49
+
50
+ def categories() @attributes.keys; end
51
+ def [](name) @attributes[name]; end
52
+
53
+ def cheat ## print cheat sheet
54
+ buf = ''
55
+ @attributes.each_with_index do |(category_name, cat),i|
56
+ buf << "#{i} - #{category_name} (#{cat.size})\n"
57
+ cat.each_with_index do |(attribute_name, _),j|
58
+ buf << " #{j} - #{attribute_name}\n"
59
+ end
60
+ end
61
+ buf
62
+ end
63
+
64
+ def export
65
+ @attributes.each_with_index do |(category_name, cat),i|
66
+ puts "==> #{category_name} - #{cat.size} record(s)..."
67
+ cat.each_with_index do |(attribute_name, img), j|
68
+ puts " #{j} - #{attribute_name} (#{img.width}x#{img.height})"
69
+
70
+ path = "./tmp/#{slug}/#{i}_#{category_name}/#{j}_#{attribute_name}"
71
+ puts path
72
+
73
+ img.save( path+".png" )
74
+ img.zoom(8).save( path+"@8x.png" )
75
+ end
76
+ end
77
+ end # method export
78
+ end # class Catalog
79
+
80
+
81
+
82
+ class Generator
83
+ def self.read( path )
84
+ catalog = Catalog.read( path )
85
+ new( catalog )
86
+ end
87
+
88
+ attr_reader :catalog
89
+
90
+ def initialize( catalog )
91
+ @catalog = catalog
92
+ end
93
+
94
+ def generate( **kwargs )
95
+ img = nil
96
+ kwargs.each do |category, name|
97
+ cat = @catalog[ category.to_s]
98
+ attribute_img = cat[name.to_s]
99
+
100
+ if attribute_img.nil?
101
+ puts "!! WARN - attribute >#{name}< in >#{category}< not found; sorry"
102
+ puts " availbable options in #{category}:"
103
+ pp cat.keys
104
+ end
105
+
106
+ img = Image.new( attribute_img.width, attribute_img.height ) if img.nil?
107
+
108
+ img.compose!( attribute_img )
109
+ end
110
+ img
111
+ end # method generate
112
+
113
+ ################
114
+ ## more convenience helpers
115
+ def cheat() @catalog.cheat; end
116
+
117
+ end # class Generator
118
+
119
+ end # module Bitgen
120
+
121
+
122
+
123
+
1
124
 
2
- puts "hello, bitgen!"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitgen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer