commit c921f2c98333fafcc9b679d34eeaac253dbe05e7 Author: Donovan Date: Wed Dec 3 11:35:39 2025 -0600 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a4dae1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_Store +__pycache__ diff --git a/davids_icons.txt b/davids_icons.txt new file mode 100644 index 0000000..4bb5b8a --- /dev/null +++ b/davids_icons.txt @@ -0,0 +1,96 @@ +citizen +butterfly +sunrise +dromedary +hiking boots +recycling bin +beef +catalogue +pug +rutabaga +sticky notes +hydrant +light +key +whisk +dog +pomegranate +owl +toast rack +horseradish +safety glasses +robot +tesla +haversack +jeans +maize +creek +jeweller +underpass +elevation +canvas tarp +railing +backyard +lava +fireplace tool set +skin +forest +dehumidifier +cycle +travel pillow +land +gale +bread pan +digger +flower pot +lamp post +twins +bead +topiary +auditorium +trooper +tray +bran +spotlight +geranium +quartz +clavicle +cactus +toilet paper roll +measuring spoon +pelican +reader +hand sanitizer holder +vine +salami +ant +ocean +engineer +pupa +hands-free speaker +mantle +icing +cat carrier +electric kettle +batting +politician +rake +seafood +backyard grill +doghouse +dentist +uncle +pet feeder +bath mat +potato masher +sorghum +tape +gift card holder +table +surfboard +screwdriver +share +toenail +oats +light snow +seagull diff --git a/main.py b/main.py new file mode 100644 index 0000000..51a2124 --- /dev/null +++ b/main.py @@ -0,0 +1,82 @@ +import os +from pathlib import Path + +from tqdm import tqdm + +from recraft_ai import generate_image_v2, sanitize_filename +from replicate_image_models import flux_schnell, nkodeicon_v1, nkodeicon_v3 + + +def run_recraft(): + icon_dir = os.path.expanduser("~/icons") + os.makedirs(icon_dir, exist_ok=True) + # style = "nature-simplism" + with open("prompts.txt", "r") as fp: + prompts = fp.readlines() + # completed = 0 + for prompt in tqdm(prompts): + # if completed == 1: + # break + # file_path = icon_dir + "/" + style + "_" + sanitize_filename(prompt) + ".svg" + file_path = icon_dir + "/" + sanitize_filename(prompt) + ".svg" + if os.path.exists(file_path): + print(f"file exists {file_path}") + continue + # generate_image_v3(prompt, Path(file_path), style) + generate_image_v2(prompt, Path(file_path)) + # completed += 1 + + +def run_flux_schnell(): + icon_dir = os.path.expanduser("~/webp_icons_background") + os.makedirs(icon_dir, exist_ok=True) + with open("prompts.txt", "r") as fp: + prompts = fp.readlines() + for prompt in tqdm(prompts): + file_path = icon_dir + "/" + sanitize_filename(prompt) + ".webp" + if os.path.exists(file_path): + print(f"file exists {file_path}") + continue + + flux_schnell( + f"simple digital art: {prompt}", + Path(file_path), + ) + + +def run_nkodeicon_v1(): + icon_dir = os.path.expanduser("~/nkodeiconv1_icons") + os.makedirs(icon_dir, exist_ok=True) + with open("prompts.txt", "r") as fp: + prompts = fp.readlines() + for prompt in tqdm(prompts): + file_path = icon_dir + "/" + sanitize_filename(prompt) + ".webp" + if os.path.exists(file_path): + print(f"file exists {file_path}") + continue + + nkodeicon_v1( + f"{prompt}", + Path(file_path), + ) + + +def run_nkodeicon_v3(): + icon_dir = os.path.expanduser("~/nkodeiconv3_icons") + os.makedirs(icon_dir, exist_ok=True) + with open("prompts.txt", "r") as fp: + prompts = fp.readlines() + for prompt in tqdm(prompts): + file_path = icon_dir + "/" + sanitize_filename(prompt) + ".webp" + if os.path.exists(file_path): + print(f"file exists {file_path}") + continue + + nkodeicon_v3( + f"{prompt}", + Path(file_path), + ) + + +if __name__ == "__main__": + run_nkodeicon_v3() diff --git a/my_iconnames.txt b/my_iconnames.txt new file mode 100644 index 0000000..724b0e5 --- /dev/null +++ b/my_iconnames.txt @@ -0,0 +1,96 @@ +outfit +seashore +cleat +dibble +carabiner clip +barometer +sickle +tractor +clavier +drafting table +kitty +racer +silver +glass jar +paint palette +thermos +phone case +cutter +garden scooper +slinky +stone +air pump +bed cover +bubble wrap +popcorn maker +glucose +scallops +architect +switchboard +staff +angora +house +gym +villa +houseboat +teaspoon +bag of chips +carriage +wave +poultry +jacket +loop +ae 86 +arkansas +avatar the last air bender +banana slug +blockchain +california +camper van +chatbot +church +coffee shop +coffee +computer networks +covid +cpu +crossfit +cryptography +donald trump +drone +dubstep +futuristic car +gpu +halo master chief +home constructions +house painting +ipa beer +jiu jitsu +kabob +kickboxer on a bag +lacrosse +las vegas red rocks +linux terminal +longboard +marriage +math equations on a chalk board +microcontroller +napa valley +ness super smash bros pk thunder +neural network +ocean waves breaking on beach +person slackline +person soldering electronics +piglet +redwood forest +rick and morty portal +road bike +robot arm +rock climbing +rocky mountains +satellite +spacex rocket +spanish moss +wife husband baby +woodshop +yoga diff --git a/my_icons.py b/my_icons.py new file mode 100644 index 0000000..5ca02c0 --- /dev/null +++ b/my_icons.py @@ -0,0 +1,28 @@ +import os +from pathlib import Path + +from tqdm import tqdm + +from recraft_ai import sanitize_filename +from replicate_image_models import nkodeicon_v3 + + +def run_nkodeicon_v3(): + icon_dir = os.path.expanduser("~/nkodeiconv3_my_icons") + os.makedirs(icon_dir, exist_ok=True) + with open("my_iconnames.txt", "r") as fp: + prompts = fp.readlines() + for prompt in tqdm(prompts): + file_path = icon_dir + "/" + sanitize_filename(prompt) + ".webp" + if os.path.exists(file_path): + print(f"file exists {file_path}") + continue + + nkodeicon_v3( + f"{prompt}", + Path(file_path), + ) + + +if __name__ == "__main__": + run_nkodeicon_v3() diff --git a/prompts.txt b/prompts.txt new file mode 100644 index 0000000..e2e01cb --- /dev/null +++ b/prompts.txt @@ -0,0 +1,967 @@ +outfit +seashore +cleat +dibble +carabiner clip +barometer +sickle +tractor +clavier +drafting table +kitty +racer +silver +glass jar +paint palette +thermos +phone case +cutter +garden scooper +slinky +stone +air pump +bed cover +bubble wrap +popcorn maker +glucose +scallops +architect +switchboard +staff +angora +house +gym +villa +houseboat +teaspoon +bag of chips +carriage +wave +poultry +jacket +loop +citizen +butterfly +sunrise +dromedary +hiking boots +recycling bin +beef +catalogue +pug +rutabaga +sticky notes +hydrant +light +key +whisk +dog +pomegranate +owl +toast rack +horseradish +safety glasses +valance +leptocephalus +haversack +jeans +maize +creek +jeweller +underpass +elevation +canvas tarp +railing +backyard +lava +fireplace tool set +skin +forest +dehumidifier +cycle +travel pillow +land +gale +bread pan +digger +flower pot +lamp post +twins +bead +topiary +auditorium +trooper +tray +bran +spotlight +geranium +quartz +clavicle +cactus +toilet paper roll +measuring spoon +pelican +reader +hand sanitizer holder +vine +salami +ant +ocean +engineer +pupa +hands-free speaker +mantle +icing +cat carrier +electric kettle +batting +politician +rake +seafood +backyard grill +doghouse +dentist +uncle +pet feeder +bath mat +potato masher +sorghum +tape +gift card holder +table +surfboard +screwdriver +share +toenail +oats +light snow +seagull +soy +grove +rhinoceros +dwelling +typewriter +stomach +valley +document +beetle +keystone +stitcher +power bank +airplane +workshop +judge +cloud +bamboo +nesting dolls +boy +floorsheet +whisker +queue barrier +garden trowel +asphalt +matter +pretzel +creamer +jet +backpack +motorboat +carrier +spark plug +bowling pin +grassland +loafer +father +axis +officer +pantry +sewing box +panel +queen +combination lock +flea comb +attachment +turtleneck sweater +ring toss +mailbox +grandchild +shorts +protection +windshield +teller +drinking glass +bear +monitor +chive +backbone +mechanism +tomato +pegboard +functional pillow +tea strainer +trapezoid +banyan +toaster +casserole dish +bathroom scale +incense +deck +alluvium +rubber band +fan +material +gondola +chives +harpsichord +comfort blanket +relish +clothing +diver +sturgeon +soda fountain +postage stamp +road +seaweed +heifer +thunderbolt +safety harness +folder +map +angiosperm +food processor +bride +pipe +light dimmer +curling iron +tissue dispenser +colander +literature book +broomstick +pet carrier +boysenberry +glasswork +socks +plumber +dhow +workbench +platinum +ravioli +compass +feeding +structure +drummer +mandarin +candy +quicksand model +sample +ceiling fan +handmade basket +shoulder +pencil holder +custard +mini hammer +jigsaw +giraffe figurine +beauty +furniture +zinc +layered cake +campanile +trapezium +circuit +tunic +colored pencils +cob +toque +line +conditioner +tap handle +cord organizer +reflector +skirting board +dream house +county +trophy +outrigger +cheek +ice +nutmeg +cage +country +mainland +crutch +mobile +driftwood +community +novel +locust +clip +book cover +craft scissors +beanie +flat +paper towel holder +paint roller +dory +bulldozer +pendulum +avenue +bandanna +palm +picnic +men +incubator +merchant +engineering +story +earbud case +houndstooth fabric +lion +boar +food storage container +mandolin +freezer +boulevard +grasshopper +arm +nitrogen +popcorn +filling tool +green +protractor +timbale +giant +stackable dresser +shin +clarinet +cocoa powder +mini air pump +curiosity +mat board +pocket watch +flip-flops +chalk +ghost +parchment +cattle +school supplies +clover +pocket bag +guitarist +cirrus +samovar +yarn spool +pump +canteen +silhouette +fluke +gift card +sunlight +kebab +beanie bag +dune +plastic bag +vault +fawn +softball +indicator +chipmunk +kitchen skimmer +emoji magnet +scout +polyester +woman +traffic cone +bakery +croissant +corridor +anatomy model +snowstorm +spy +wallet organizer +battery holder +shawl +muffin tin +puffin +passage +footrest +bicycle fender +woolens +scarf holder +deputy +tiny book +pasta +bifocals +telescope stand +fire bowl +hush puppy +feather +reusable rag +grouper +nun +sun +ruby +place +pop +classroom +footstool +leaf +lung +dill +frontier +stereo +portrait +blackberry +earplug +display +apricot +bicycle horn +paramecium +boot +carp +grey +lock +fur +necklace stand +billboard +starter +cord +conductor +elm +silicon +tube +orchid +artifact +movie +dog bowl +crayfish +investigator +skull +cylinder +racing bike +bowling ball +gazebo +spectacles +fender +slate +orangutan +step +umbrella holder +shiny coin +dishwasher +glow +ferryboat +undershirt +mailman +turtle figure +yardstick +knitting +handsaw +makeup +strawberry +wild +bottle cap +speakerphone +vacation journal +press +mover +courtroom +carpet cleaner +billiard ball +packaging +cravat +crepe +spork +commander +camera +jug +collectible card +beech +fingerling +gearshift +bathrobe +pizza sheet +neon +casserole +chrysalis +scented candle holder +lawn mower bag +airfield +cushion +lace +petal +seal +wharf +snack +shoe cleaner +oasis +spike ball +intestine +dolphin +film +salsa +knuckle +desert +comestible +linseed +marble cake +column +pruner +exercise ball +napkin +tunnel +safety seat +saddlebag +hardboard +lark +cod +neighbourhood +volcano +roller +snow shovel +cephalopod +cloudburst +stackable baskets +rail +gap +puppy toy +grand +paste +zucchini +mustache +scientist +gentleman +mechanic +mocktail +mail +wireless charger +yarmulke +stocking holder +shallot +longboat +washbasin +iceberg +rubber stamp +pup +hyena +wardrobe +snack stack +roundabout +bark +signal +icecream +contrail +millstone +loft +page +sneakers +folding chair +yoga mat +ark +paperweight +backpack organizer +lasagna +scholar's notebook +stamen +copper +swimsuit +turkey +canned food +catch +bullet journal +calculator +barbecue grill +hovercraft +outdoor light fixture +hat +periodical +wrestler +toothbrush +stretch +transportation +meteor +skateboard +dollhouse +sofa +oxford +grill +fritter +trellis +button +moth +sherbet +frying pan +salmon +fire pit +plaster +spade +puma +endive +sandcastle mold +doe +sepal +cheesecake +coast +saxophone +kazoo +pathway +loggia +lemon squeezer +web +e-book +barrier +muffin +mother +rose +rancher +slapstick +castle +sprat +foodstuffs +waitress +nurse +bone +stonework +tripod +accordion +rest +hershey's kiss +fishbone +wing +pea +icicle +cereal box +potholder +squash +cocoa +birdhouse +tom-tom +stump +field +balloon +stress ball +instructor +train +protein +car seat cover +garden stake +perfume +ham +chair +rhubarb +shelf +windshield wiper +yarn +hut +speedboat +artichoke +album +shipping box +desk +bugle +justice +hovel +spine +heartwood +photograph frame +antler +aquarium +anchovy +blowhole +windbreaker +penguin +seed +omelet +oregano +bush +pamphlet +duck +SUV +keyboard +clipper +wrapper +lap +businessman +cousin +gaiters +glass make-up container +ladle +barbeque +nickel +pilgrim +trainer +map stand +passport +security fence +luggage +captain +lemur +vegetable peeler +scanner +herb +fleece +snowman +curtains +slot +food +lookout +fruit +dreamcatcher +jotter +luggage conveyor +gadget +sunflower +city +sourwood +neighbor +hop +mutton +hog +pin +paperback +romaine +earthenware pot +schnitzel +taxi +coffee +butcher block +friend +typing paper +scratch paper +torte +ship model +garden shovel +insulated tumbler +water balloon +cricketer +espadrille +residence +lobby +spot +stall +play-doh +trash +slipcover +nerf gun +spatula +buddy +landscaping book +storage +kitchen tool +body pillow +ugly doll +bill organizer +flute +monocle +range +step stool +drums +beverage +camel +watercress +section +factory +aluminium +bow +ram's horn +drizzle +bookcase +oatmeal +condor +claw +dirndl +bell +ballot box +plumb bob +art smock +scissors +chauffeur +lapdog +fan blade +den +oar +whirlwind +sink +door ajar +faucet +recliner +gel pen +bird +yurt +son +vinegar +airship +ketch +panther +paint +throne +horse +freckle +yard +pavilion +curved ruler +kitchen organizer +wooden block +processor +veil +sweater +kit +folding table +cabin +olive +smart speaker +spectacle +binoculars +author +measuring tape +suburb +vestment +mill +wool blanket +buzzard +treasury +sage +decoration +beard +craftsman +sausage +handle +fish bowl +edible flower +wolf +slippers +bronco +garment +defibrillator +colorful hat +iron key +jaw +plush toy +tote bag +doctor +egg timer +blueberry +unicycle +salon +trunk +bandana +south +noodles +space +wilderness +tanker +nail +clutch purse +abdomen +dictionary +portfolio +kiwi +cufflinks +siding +woodchuck +magic wand +brain +capital +watchband +galley +garden rake +comb +herring +bonsai +balloonist +tourist +lamb +parachute +cub +hot glue gun +background +swamp +gazelle +symmetry +patty +lilac +arch +livestock +ceiling +knitting needles +orange +thunder +pasta container +row +photo book +cable +unit +salad spinner +lemon +puzzle piece +bento box +rosemary +whistle +basin +barbecue skewer +mouse pad +raisin +appetizer fork +cat bed +chowder +hub +supermarket +water canister +detective +floor +badger +box +ruler +loofah +parka +sheet +holder +fruit bowl +satellite +medicine +churn +cannon +hip +child +filter +lipstick +shoe +mop +drop +blackbird +flippers +steamer +puzzle mat +hangar +auto +vest +peacoat +kohlrabi +baggage +viewer +bouquet +chest +leg +bike lock +lid +basil +ear +anise +papa +sombrero +photo printer +hiking stick +thunderstorm +insect house +limestone +baseball cap +laundry +paradise +exit +tart +divider +crawdad +charm +curtain rod +pickaxe +cat stand diff --git a/recraft_ai.py b/recraft_ai.py new file mode 100644 index 0000000..14bb6f5 --- /dev/null +++ b/recraft_ai.py @@ -0,0 +1,78 @@ +import re +from os import getenv +from pathlib import Path + +import requests +from openai import OpenAI + +API_KEY = getenv("RECRAFT_API_TOKEN") +client = OpenAI(base_url="https://external.api.recraft.ai/v1", api_key=API_KEY) + +styles = {"nature-simplism": "ee2bb119-a790-409f-888e-b4b7b73f0aa0"} + + +def generate_image_v3(prompt: str, file_path: Path, style: str): + response = client.images.generate( + prompt=prompt, + size="1024x1024", + model="recraftv3", + extra_body={ + "style_id": styles[style], + }, + ) + image_url = response.data[0].url + if not image_url: + raise ValueError("No image URL returned by the API.") + + img_response = requests.get(image_url) + if img_response.status_code != 200: + raise IOError(f"Failed to download image from {image_url}") + + with open(file_path, "wb") as f: + f.write(img_response.content) + + +def generate_image_v2(prompt: str, file_path: Path): + response = client.images.generate( + prompt=prompt, + size="1024x1024", + model="recraftv2", + style="icon", + ) + image_url = response.data[0].url + if not image_url: + raise ValueError("No image URL returned by the API.") + + img_response = requests.get(image_url) + if img_response.status_code != 200: + raise IOError(f"Failed to download image from {image_url}") + + with open(file_path, "wb") as f: + f.write(img_response.content) + + +def sanitize_filename(name: str) -> str: + # Define illegal characters (union of Windows + Unix) + illegal_chars = r'[\\\/:*?"<>|]' + + # Replace spaces and illegal characters with "_" + name = re.sub(r"\s", "_", name) + name = re.sub(illegal_chars, "_", name) + + # Windows also doesn't allow names ending in . or space + name = name.rstrip(" .") + + # Windows reserved device names + reserved_names = { + "CON", + "PRN", + "AUX", + "NUL", + *(f"COM{i}" for i in range(1, 10)), + *(f"LPT{i}" for i in range(1, 10)), + } + name_upper = name.upper().split(".")[0] + if name_upper in reserved_names: + name = f"_{name}" + + return name diff --git a/replicate_image_models.py b/replicate_image_models.py new file mode 100644 index 0000000..ba685bd --- /dev/null +++ b/replicate_image_models.py @@ -0,0 +1,67 @@ +from pathlib import Path + +import replicate + + +def flux_schnell(prompt: str, file_path: Path): + output = replicate.run( + "black-forest-labs/flux-schnell", + input={ + "prompt": prompt, + "go_fast": True, + "megapixels": "0.25", + "num_outputs": 1, + "aspect_ratio": "1:1", + "output_format": "webp", + "output_quality": 80, + "num_inference_steps": 4, + }, + ) + with open(file_path, "wb") as fp: + fp.write(output[0].read()) + + +def nkodeicon_v1(prompt: str, file_path: Path): + output = replicate.run( + "donovankelly/nkodeicon-v1:761f0a14dbef2a9cd4d65fbb19f613209f7e3eb151c42ec9a5ee775d30e83e9b", + input={ + "model": "dev", + "prompt": f"TOK {prompt} on a white background", + "go_fast": True, + "lora_scale": 1.5, + "megapixels": "0.25", + "num_outputs": 1, + "aspect_ratio": "1:1", + "output_format": "webp", + "guidance_scale": 3.5, + "output_quality": 100, + "prompt_strength": 0.8, + "extra_lora_scale": 1.5, + "num_inference_steps": 28, + }, + ) + with open(file_path, "wb") as fp: + fp.write(output[0].read()) + + +def nkodeicon_v3(prompt: str, file_path: Path): + output = replicate.run( + "donovankelly/nkodeicon-v3:12fa3b15dd48dc3081642572f2cb7fd18652086f19133dddd4b666f4c7455752", + input={ + "model": "dev", + "prompt": f"ICON colorful {prompt} on a white background", + "go_fast": True, + "lora_scale": 1, + "megapixels": "0.25", + "num_outputs": 1, + "aspect_ratio": "1:1", + "output_format": "webp", + "guidance_scale": 3, + "output_quality": 80, + "prompt_strength": 0.8, + "extra_lora_scale": 1, + "num_inference_steps": 50, + }, + ) + with open(file_path, "wb") as fp: + fp.write(output[0].read())