Last active
March 23, 2023 15:22
-
-
Save Oldes/b7b1f62dd3da181d345505fbc407f048 to your computer and use it in GitHub Desktop.
Reproducing images with geometric primitives
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
REBOL [ | |
Title: "Reproducing images with geometric primitives." | |
type: module | |
name: primitive | |
date: 22-Mar-2023 | |
author: "Oldes" | |
version: 0.1.0 | |
license: MIT | |
purpose: {This is a try to have something like this https://github.com/fogleman/primitive} | |
exports: [primitivize] | |
needs: [3.10.5 blend2d] | |
usage: [primitivize/with %source.jpg [max-steps 2000 seed 12 save %result.jpg]] | |
] | |
primitivize: function [ | |
source [image! file!] | |
/with options [block!] | |
][ | |
unless image? source [ source: load :source ] | |
if source/size/x > 256 [ source: resize source 256 ] | |
size: source/size | |
output: make image! size | |
temp1: make image! size | |
temp2: make image! size | |
;; initial image difference | |
dif: image-diff source output | |
max-radius: 100 | |
max-steps: 1000 | |
max-similarity: 1% | |
mod-radius: 0.9 | |
out-file: none | |
alpha: 0.7 | |
step: 0 | |
if options [ | |
parse options [any [ | |
'max-radius set v: number! (max-radius: v) | |
| 'mod-radius set v: number! (mod-radius: min v 1.0) | |
| 'max-steps set v: number! (max-steps: v) | |
| 'max-similarity set v: number! (max-similarity: v) | |
| 'alpha set v: number! (alpha: min v 1.0) | |
| 'seed set v: skip (random/seed :v) | |
| 'save set v: file! (out-file: v) | |
| skip | |
]] | |
] | |
;commands: ['fill clr 'circle pos random max-radius] | |
commands: ['fill clr 'rotate random 360 pos 'circle pos random max-radius random max-radius] | |
all-commands: make block! max-steps * 9 | |
until [ | |
pos: random size | |
clr: pick source pos | |
;; drawing with reduced opacity | |
clr/4: alpha * clr/4 | |
;; draw 2 versions and use the one with better result | |
change temp1 output | |
change temp2 output | |
draw temp1 c1: reduce commands | |
draw temp2 c2: reduce commands | |
d1: image-diff source temp1 | |
d2: image-diff source temp2 | |
;print ["diffs:" d1 tab d2] | |
either any [ | |
d1 < dif | |
d2 < dif | |
][ | |
++ step | |
;; Use the better version as a new output and store its draw commands, | |
;; so the image may be later be redrawn in a higher resolution. | |
dif: either d1 < d2 [ | |
change output temp1 | |
append append all-commands c1 'reset-matrix | |
;probe c1 | |
d1 | |
][ | |
change output temp2 | |
append append all-commands c2 'reset-matrix | |
;probe c2 | |
d2 | |
] | |
print ["Step:" step " with diff:" dif] | |
;; lower the maximum size of objects with increased steps.. | |
;; (initially drawing larger objects and then smaller and smaller) | |
max-radius: 100 * (1.1 - (step / max-steps)) | |
][ | |
;; None of the new versions have better result! | |
;; Try smaller object where is better chance to have improved similarity. | |
max-radius: max-radius * mod-radius | |
if max-radius < 1 [ | |
;; If still not able to improve the output, then stop trying | |
;; to prevent infinite loop... | |
break | |
] | |
] | |
;; stop continuation if... | |
any [ | |
step = max-steps ;; maximum number of primitives reached | |
dif < max-similarity ;; or the output image is already good enough | |
] | |
] | |
;; Use collected draw commands scaled 400% | |
;; Unfortunatelly current draw does not provide nested transformations, | |
;; so I must change values manually:/ | |
size-4: 4 * size | |
parse all-commands [any [ | |
'rotate skip v: (change v 4 * v/1) skip | |
| 'circle v: ( | |
change v 4 * v/1 ++ v | |
change v 4 * v/1 ++ v | |
change v 4 * v/1 | |
) 3 skip | |
| skip | |
]] | |
out-4x: draw size-4 all-commands | |
save %result-4x.jpg out-4x | |
;; Save the original output result... | |
if out-file [ | |
try/except [ | |
save out-file output | |
][ print ["Failed to save file:" out-file] ] | |
] | |
output | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment