bitgen 0.0.1 → 0.1.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 +4 -4
- data/CHANGELOG.md +1 -0
- data/README.md +268 -1
- data/Rakefile +1 -1
- data/lib/bitgen.rb +123 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d2da11669caadb65ebcb6af3a302c732af8b015b30c6c6ef8dc7d19db553b4d
|
4
|
+
data.tar.gz: cac6c0f92e52cb2e8dda34d2d29e1f114bd4109704d1b55404145d4b9c4be318
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a43a312e44c8a928b41d455ea68e42e86fb24a74ae2ca8bb52f559c93a1039379c075bbd823e059a264b9d463e407abd1ce1eae35fb55cbcad0f7ce7aa2bc09a
|
7
|
+
data.tar.gz: d40be4d2466d90db4975550c8c4330884c72d6bf6a3d91d9265a6f094b30e8e55eb39755a524d69d729d6782515c14abfe2a3fee5feef2041c4ecc2ef1865c21
|
data/CHANGELOG.md
CHANGED
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
|
-
|
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
|
+

|
83
|
+

|
84
|
+

|
85
|
+
|
86
|
+
in 4x:
|
87
|
+
|
88
|
+

|
89
|
+

|
90
|
+

|
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
|
+

|
271
|
+

|
272
|
+

|
273
|
+

|
274
|
+
|
275
|
+
in 4x:
|
276
|
+
|
277
|
+

|
278
|
+

|
279
|
+

|
280
|
+

|
281
|
+
|
282
|
+
|
283
|
+
|
284
|
+
That's it for now.
|
18
285
|
|
19
286
|
|
20
287
|
|
data/Rakefile
CHANGED
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!"
|