Add files via upload
This commit is contained in:
+15
-3
@@ -13,6 +13,10 @@ from .fl_glitch import FL_Glitch
|
||||
from .fl_ripple import FL_Ripple
|
||||
from .fl_pixelsort import FL_PixelSort
|
||||
from .fl_hexagonalpattern import FL_HexagonalPattern
|
||||
from .fl_nftgenerator import FL_NFTGenerator
|
||||
from .fl_halftone import FL_HalftonePattern
|
||||
from. fl_randomrange import FL_RandomNumber
|
||||
from. fl_promptselector import FL_PromptSelector
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +35,11 @@ NODE_CLASS_MAPPINGS = {
|
||||
"FL_Glitch": FL_Glitch,
|
||||
"FL_Ripple": FL_Ripple,
|
||||
"FL_PixelSort": FL_PixelSort,
|
||||
"FL_HexagonalPattern": FL_HexagonalPattern
|
||||
"FL_HexagonalPattern": FL_HexagonalPattern,
|
||||
"FL_NFTGenerator": FL_NFTGenerator,
|
||||
"FL_HalftonePattern": FL_HalftonePattern,
|
||||
"FL_RandomNumber": FL_RandomNumber,
|
||||
"FL_PromptSelector": FL_PromptSelector
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -44,12 +52,16 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"FL_AudioFrameCalculator": "FL Audio Scanner",
|
||||
"FL_CodeNode": "FL Code Node",
|
||||
"FL_ImagePixelator": "FL Image Pixelator",
|
||||
"FL_DirectoryCrawl": "FL DirectoryCrawl",
|
||||
"FL_DirectoryCrawl": "FL Directory Crawl",
|
||||
"FL_Ascii": "FL Ascii",
|
||||
"FL_Glitch": "FL Glitch",
|
||||
"FL_Ripple": "FL Ripple",
|
||||
"FL_PixelSort": "FL PixelSort",
|
||||
"FL_HexagonalPattern": "FL Hexagonal Pattern"
|
||||
"FL_HexagonalPattern": "FL Hexagonal Pattern",
|
||||
"FL_NFTGenerator": "FL NFT Generator",
|
||||
"FL_HalftonePattern": "FL Halftone",
|
||||
"FL_RandomNumber": "FL Random Number",
|
||||
"FL_PromptSelector": "FL Prompt Selector"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import torch
|
||||
import numpy as np
|
||||
import sys
|
||||
|
||||
class FL_HalftonePattern:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"images": ("IMAGE",),
|
||||
},
|
||||
"optional": {
|
||||
"dot_size": ("INT", {"default": 5, "min": 1, "max": 20, "step": 1}),
|
||||
"dot_spacing": ("INT", {"default": 10, "min": 5, "max": 50, "step": 1}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "halftone_pattern"
|
||||
CATEGORY = "🏵️Fill Nodes"
|
||||
|
||||
def halftone_pattern(self, images, dot_size=5, dot_spacing=10):
|
||||
out = []
|
||||
total_images = len(images)
|
||||
for i, img in enumerate(images, start=1):
|
||||
img_np = img.cpu().numpy().squeeze()
|
||||
grayscale_image = np.dot(img_np[..., :3], [0.299, 0.587, 0.114])
|
||||
height, width = grayscale_image.shape
|
||||
|
||||
halftone_image = np.ones((height, width), dtype=np.float32)
|
||||
|
||||
for y in range(0, height, dot_spacing):
|
||||
for x in range(0, width, dot_spacing):
|
||||
box = (x, y, x + dot_spacing, y + dot_spacing)
|
||||
region_mean = np.mean(grayscale_image[box[1]:box[3], box[0]:box[2]])
|
||||
dot_radius = int((1 - region_mean) * dot_size / 2)
|
||||
dot_position = (x + dot_spacing // 2, y + dot_spacing // 2)
|
||||
|
||||
# Create a circular mask for the dot
|
||||
y_grid, x_grid = np.ogrid[-dot_radius:dot_radius + 1, -dot_radius:dot_radius + 1]
|
||||
mask = x_grid ** 2 + y_grid ** 2 <= dot_radius ** 2
|
||||
|
||||
# Apply the dot mask to the halftone image
|
||||
y_start = max(0, dot_position[1] - dot_radius)
|
||||
y_end = min(height, dot_position[1] + dot_radius + 1)
|
||||
x_start = max(0, dot_position[0] - dot_radius)
|
||||
x_end = min(width, dot_position[0] + dot_radius + 1)
|
||||
|
||||
# Ensure the mask dimensions match the sliced halftone image dimensions
|
||||
mask_height = y_end - y_start
|
||||
mask_width = x_end - x_start
|
||||
mask = mask[:mask_height, :mask_width]
|
||||
|
||||
halftone_image[y_start:y_end, x_start:x_end][mask] = 0
|
||||
|
||||
o = np.stack((halftone_image,) * 3, axis=-1)
|
||||
o = torch.from_numpy(o).unsqueeze(0)
|
||||
out.append(o)
|
||||
|
||||
# Print progress update
|
||||
progress = i / total_images * 100
|
||||
sys.stdout.write(f"\rProcessing images: {progress:.2f}%")
|
||||
sys.stdout.flush()
|
||||
|
||||
# Print a new line after the progress update
|
||||
print()
|
||||
|
||||
out = torch.cat(out, 0)
|
||||
return (out,)
|
||||
@@ -0,0 +1,85 @@
|
||||
import os
|
||||
import random
|
||||
from PIL import Image
|
||||
import torch
|
||||
import numpy as np
|
||||
|
||||
class FL_NFTGenerator:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"folder_path": ("STRING", {"default": ""}),
|
||||
"dummy_seed": ("INT", {"default": 0, "min": 0, "max": 1000000}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "IMAGE")
|
||||
FUNCTION = "generate_nft"
|
||||
CATEGORY = "🏵️Fill Nodes"
|
||||
|
||||
def t2p(self, t):
|
||||
if t is not None:
|
||||
i = 255.0 * t.cpu().numpy().squeeze()
|
||||
p = Image.fromarray(np.clip(i, 0, 255).astype(np.uint8))
|
||||
return p
|
||||
|
||||
def generate_nft(self, folder_path, dummy_seed):
|
||||
if not os.path.exists(folder_path):
|
||||
raise ValueError(f"Folder path does not exist: {folder_path}")
|
||||
|
||||
image_files = [f for f in os.listdir(folder_path) if not f.lower().endswith("-mask.png") and not f.lower().endswith("-mask.jpg") and not f.lower().endswith("-mask.jpeg")]
|
||||
if not image_files:
|
||||
raise ValueError(f"No image files found in the folder: {folder_path}")
|
||||
|
||||
# Extract rarity percentages from image filenames
|
||||
rarities = []
|
||||
for image_file in image_files:
|
||||
if "-" in image_file:
|
||||
rarity_str = image_file.split("-")[1].split("per")[0]
|
||||
rarity = int(rarity_str)
|
||||
rarities.append(rarity)
|
||||
else:
|
||||
raise ValueError(f"Invalid image filename format: {image_file}")
|
||||
|
||||
# Calculate cumulative probabilities
|
||||
total_rarity = sum(rarities)
|
||||
probabilities = [rarity / total_rarity for rarity in rarities]
|
||||
cumulative_probabilities = [sum(probabilities[:i+1]) for i in range(len(probabilities))]
|
||||
|
||||
# Generate a random number between 0 and 1 using the dummy seed
|
||||
random.seed(dummy_seed)
|
||||
random_number = random.random()
|
||||
|
||||
# Find the index of the selected image based on the random number and cumulative probabilities
|
||||
selected_index = None
|
||||
for i, prob in enumerate(cumulative_probabilities):
|
||||
if random_number <= prob:
|
||||
selected_index = i
|
||||
break
|
||||
|
||||
if selected_index is None:
|
||||
raise ValueError("Failed to select an image based on rarity.")
|
||||
|
||||
# Get the selected image and its corresponding mask
|
||||
selected_image_file = image_files[selected_index]
|
||||
selected_image_path = os.path.join(folder_path, selected_image_file)
|
||||
selected_image = Image.open(selected_image_path)
|
||||
|
||||
# Get the file extension of the selected image
|
||||
_, extension = os.path.splitext(selected_image_file)
|
||||
|
||||
# Generate the mask filename based on the selected image filename
|
||||
mask_file = selected_image_file.rsplit(".", 1)[0] + "-mask" + extension
|
||||
mask_path = os.path.join(folder_path, mask_file)
|
||||
|
||||
if os.path.exists(mask_path):
|
||||
mask_image = Image.open(mask_path)
|
||||
else:
|
||||
# Create a blank mask image if the corresponding mask is not found
|
||||
mask_image = Image.new("RGB", selected_image.size, (0, 0, 0))
|
||||
|
||||
selected_image_tensor = torch.from_numpy(np.array(selected_image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||
mask_image_tensor = torch.from_numpy(np.array(mask_image).astype(np.float32) / 255.0).unsqueeze(0)
|
||||
|
||||
return (selected_image_tensor, mask_image_tensor)
|
||||
@@ -0,0 +1,36 @@
|
||||
class FL_PromptSelector:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"prepend_text": ("STRING", {"multiline": True, "default": ""}),
|
||||
"prompts": ("STRING", {"multiline": True}),
|
||||
"append_text": ("STRING", {"multiline": True, "default": ""}),
|
||||
"index": ("INT", {"default": 0, "min": 0, "max": 100, "step": 1}),
|
||||
},
|
||||
"optional": {},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
FUNCTION = "select_prompt"
|
||||
CATEGORY = "🏵️Fill Nodes"
|
||||
|
||||
def select_prompt(self, prepend_text, prompts, append_text, index):
|
||||
prepend_text = prepend_text.strip()
|
||||
prompt_lines = prompts.split("\n")
|
||||
append_text = append_text.strip()
|
||||
|
||||
num_prompts = len(prompt_lines)
|
||||
|
||||
if index < 0 or index >= num_prompts:
|
||||
raise ValueError(f"Index {index} is out of range. Please provide an index between 0 and {num_prompts - 1}.")
|
||||
|
||||
selected_prompt = prompt_lines[index].strip()
|
||||
|
||||
if prepend_text:
|
||||
selected_prompt = prepend_text + " " + selected_prompt
|
||||
|
||||
if append_text:
|
||||
selected_prompt = selected_prompt + " " + append_text
|
||||
|
||||
return (selected_prompt,)
|
||||
@@ -0,0 +1,38 @@
|
||||
import random
|
||||
import torch
|
||||
|
||||
class FL_RandomNumber:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {},
|
||||
"optional": {
|
||||
"min_value": ("FLOAT", {"default": 0.0, "min": -1000000.0, "max": 1000000.0, "step": 0.1}),
|
||||
"max_value": ("FLOAT", {"default": 1.0, "min": -1000000.0, "max": 1000000.0, "step": 0.1}),
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 1000000}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT", "FLOAT")
|
||||
FUNCTION = "generate_random_number"
|
||||
CATEGORY = "🏵️Fill Nodes"
|
||||
|
||||
def generate_random_number(self, min_value=0.0, max_value=1.0, seed=0):
|
||||
if min_value > max_value:
|
||||
raise ValueError("min_value should be less than or equal to max_value")
|
||||
|
||||
# Generate a random seed if seed is 0
|
||||
if seed == 0:
|
||||
seed = random.randint(1, 1000000)
|
||||
|
||||
# Set the random seed for reproducibility
|
||||
random.seed(seed)
|
||||
torch.manual_seed(seed)
|
||||
|
||||
# Generate a random float value within the specified range
|
||||
random_float = min_value + (max_value - min_value) * random.random()
|
||||
|
||||
# Generate a random integer value within the specified range
|
||||
random_int = int(min_value + (max_value - min_value) * random.random())
|
||||
|
||||
return (random_int, random_float)
|
||||
Reference in New Issue
Block a user