Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MODKILLER1001/5bf736aa2e3493b683366d3dd556c141 to your computer and use it in GitHub Desktop.
Save MODKILLER1001/5bf736aa2e3493b683366d3dd556c141 to your computer and use it in GitHub Desktop.
Quick tool that generates a function that displays particles for an input image using local coordinates. Drop images in the `images` folder in the same directory as the script. You'll also need to `pip install opencv-python`. Edit generation options at the bottom of the file.
import cv2
import os
class ImageToParticle:
def __init__(self, image_file, resolution=(40, 80), scale=0.25, max_size=5, replace_transparent=[], commands=[], show_display=False):
self.image_file = image_file # Source file
self.resolution = resolution # Restrict number of pixels to generate
self.scale = scale # Scale the size of image displayed in game
self.max_size = max_size # Maximum particle size, alpha scales this if replace_transparent is not defined
self.replace_transparent = replace_transparent # RGB value to replace 0 alpha with
self.commands = commands # Additional commands to add to start of each function
self.show_display = show_display # Display resized image for debugging
def create_path(self, filepath):
if not os.path.exists(filepath):
try:
os.makedirs(filepath)
except OSError as exc: # Guard against race condition
if exc.errno != errno.EEXIST:
raise
def create_file(self, filename, contents):
self.create_path(os.path.dirname(filename))
with open(filename, 'w', encoding='utf-8') as f:
f.writelines(contents)
def create_empty_function_folder(self, paths):
self.create_path(paths["functions"])
def get_color(self, pixel):
if len(pixel) > 3:
if pixel[3] == 0.0 and len(self.replace_transparent) != 3:
# Replace full transparency with value
return "{0} {1} {2} {3}".format(self.replace_transparent[0], self.replace_transparent[1], self.replace_transparent[2], self.max_size)
elif len(self.replace_transparent) == 3:
return "{0} {1} {2} {3}".format(pixel[0]/256, pixel[1]/256, pixel[2]/256, self.max_size * pixel[3]/256)
return "{0} {1} {2} {3}".format(pixel[0]/256, pixel[1]/256, pixel[2]/256, self.max_size)
def get_position(self, row, col):
return "^{0} ^{1} ^0".format(row*self.scale, col*self.scale)
def generate(self):
image_prefix = "image_"
datapack_name = image_prefix + os.path.basename(os.path.splitext(self.image_file)[0]).lower().replace(" ","_")
paths = {
"functions": "particle_images"
}
self.create_empty_function_folder(paths)
image = cv2.imread(self.image_file, cv2.IMREAD_UNCHANGED)
function_contents = []
image_size = [image.shape[0], image.shape[1]]
if image_size[0] > self.resolution[0]:
scale = self.resolution[0] / image_size[0]
image_size[1] = int(image_size[1] * scale)
image_size[0] = self.resolution[0]
if image_size[1] > self.resolution[1]:
scale = self.resolution[1] / image_size[1]
image_size[0] = int(image_size[0] * scale)
image_size[1] = self.resolution[1]
image = cv2.resize(image, (image_size[1], image_size[0]))
output = []
output += self.commands
for col in range(image.shape[0]):
colors = []
for row in range(image.shape[1]):
pixel = image[image.shape[0] - 1 - col, image.shape[1] - 1 - row]
if len(pixel) > 3:
color = self.get_color([pixel[2], pixel[1], pixel[0], pixel[3]])
else:
color = self.get_color([pixel[2], pixel[1], pixel[0]])
position = self.get_position(row - image.shape[1]/2, col - image.shape[0]/2)
text_json = 'particle dust {0} {1} 0 0 0 0 0 force'.format(color, position)
colors.append(text_json)
colors.append(text_json)
output.append('\n'.join(colors))
output = '\n'.join(output)
function_contents.append(output)
if self.show_display:
cv2.imshow('image',image)
cv2.waitKey(0)
self.create_file(os.path.join(paths["functions"], "{0}.mcfunction".format(datapack_name)), '\n'.join(function_contents))
if __name__ == '__main__':
for file in os.listdir("images"):
# With 0 alpha replacement, particles won't scale
#image = ImageToParticle(os.path.join("images", file), resolution=(40, 80), scale=0.8, max_size=5, replace_transparent=[1.0, 1.0, 1.0], commands=[], show_display=False)
# Without 0 alpha replacement, scales particle size by alpha
image = ImageToParticle(os.path.join("images", file), resolution=(40, 80), scale=0.8, max_size=5, commands=[], show_display=False)
image.generate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment