idname="Color", default=(0, 0, 0, 255), label="Image Color:" ) self.size_prop = api.SizeProp( idname="Size", default=[255, 255], label="Image Size:" ) self.NodeAddProp(self.color_prop) self.NodeAddProp(self.size_prop) def WidgetEventHook(self, idname, value): if idname == "Color": img = self.NodeEvaluation(EvalInfo(self)).GetImage() self.NodeSetThumb(img, force_refresh=True) self.RefreshPropertyPanel() def NodeEvaluation(self, eval_info): color = eval_info.EvaluateProperty('Color') imgsize = eval_info.EvaluateProperty('Size') image = api.RenderImage() image.SetAsImage(Image.new("RGBA", (imgsize[0], imgsize[1]), color)) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ColorImageNode, "corenode_colorimage")
self.NodeSetThumb(self.Model.GetThumbImage()) @property def NodeMeta(self): meta_info = { "label": "Output", "author": "Correct Syntax", "version": (0, 1, 3), "supported_app_version": (0, 5, 0), "category": "OUTPUT", "description": """The most important node of them all. :) This is registered here for the UI -the evaluation is handled elsewhere. This node should not be accessed by outside users. """ } return meta_info def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): pass api.RegisterNode(OutputNode, "corenode_outputcomposite")
def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Radius", default=1, min_val=1, max_val=25, widget=api.SLIDER_WIDGET, label="Radius:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') radius = eval_info.EvaluateProperty('Radius') image = api.RenderImage() image.SetAsImage(image1.GetImage().filter( ImageFilter.GaussianBlur(radius) ).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(BlurNode, "corenode_blur")
self.NodeAddProp(p2) self.NodeAddProp(p3) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') saturation_val = eval_info.EvaluateProperty('Saturation') brightness_val = eval_info.EvaluateProperty('Brightness') gamma_val = eval_info.EvaluateProperty('Gamma') # Convert the current image data to an array # that we can use and greyscale it. im = ArrayFromImage(image1.GetImage()) gray_scale_img = cv2.equalizeHist(cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)) generated_bump_map = self.ComputeBumpMap(gray_scale_img, saturation_val, brightness_val, gamma_val) image = api.RenderImage() image.SetAsImage(ArrayToImage(generated_bump_map).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ToBumpMapNode, "corenode_tobumpmap")
def NodeEvaluation(self, eval_info): path = eval_info.EvaluateProperty('File Path') image = api.RenderImage() if path != "": if self._cachedPath != path: try: image.SetAsOpenedImage(path) img = image.GetImage().convert('RGBA') self._cachedPath = path self._cachedImage = img image.SetAsImage(img) except FileNotFoundError: print("FILE NOT FOUND") else: image.SetAsImage(self._cachedImage) # if path != '': # try: # image.SetAsOpenedImage(path) # image.SetAsImage(image.GetImage().convert('RGBA')) # except FileNotFoundError: # pass self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ImageNode, "corenode_image")
self.NodeAddProp(p4) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') saturation_val = eval_info.EvaluateProperty('Saturation') brightness_val = eval_info.EvaluateProperty('Brightness') gamma_val = eval_info.EvaluateProperty('Gamma') threshold_val = eval_info.EvaluateProperty('Threshold') # Convert the current image data to an array # that we can use and greyscale it. im = ArrayFromImage(image1.GetImage()) gray_scale_img = cv2.equalizeHist(cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)) generated_ao_map = self.ComputeAOMap(gray_scale_img, saturation_val, brightness_val, gamma_val, threshold_val) image = api.RenderImage() image.SetAsImage(ArrayToImage(generated_ao_map).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ToAOMapNode, "corenode_toaomap")
intensity_val = eval_info.EvaluateProperty('Intensity') # Convert the current image data to an array that scipy can use im = ArrayFromImage(image1.GetImage()) # Create the image if im.ndim == 3: im_grey = np.zeros((im.shape[0], im.shape[1])).astype(float) im_grey = (im[..., 0] * 0.3 + im[..., 1] * 0.6 + im[..., 2] * 0.1) im = im_grey im_smooth = self.SmoothGaussian(im, sigma_val) sobel_x, sobel_y = self.Sobel(im_smooth) # Calculate the normal map generated_normal_map = self.ComputeNormalMap( sobel_x, sobel_y, intensity_val ) image = api.RenderImage() image.SetAsImage( ArrayToImage(generated_normal_map).convert('RGBA') ) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ToNormalMapNode, "corenode_tonormalmap")
#draw.multiline_text(text_pos, text, font=fnt, fill=font_color) print(font_size, "size") draw_text = ImageDraw.Draw(text_image) text_font = ImageFont.truetype(font="C:/Windows/Fonts/arial.ttf", size=30) # Draw the text draw_text.text(xy=(0, 0), text="text", font=text_font, fill="black", spacing=6, align='left', stroke_width=1, stroke_fill="blue") # Composite the two images together composited_image = Image.alpha_composite(main_image.GetImage(), text_image) image.SetAsImage(composited_image) self.NodeSetThumb(image.GetImage()) print("yes-past") return image # Register the node api.RegisterNode(TextNode, "corenode_text")
self.NodeAddProp(self.color2_prop) self.NodeAddProp(self.size_prop) def WidgetEventHook(self, idname, value): if idname in ["Color 1", "Color 2"]: img = self.NodeEvaluation(EvalInfo(self)).GetImage() self.NodeSetThumb(img, force_refresh=True) self.RefreshPropertyPanel() def NodeEvaluation(self, eval_info): gradient = 0.5 # eval_info.EvaluateProperty('Gradient') color1 = eval_info.EvaluateProperty('Color 1') color2 = eval_info.EvaluateProperty('Color 2') imgsize = eval_info.EvaluateProperty('Size') gradientimage = Image.new("L", (imgsize[0], 1)) for x in range(imgsize[0]): gradientimage.putpixel( (x, 0), int(225. * (1. - float(gradient) * float(x) / imgsize[0]))) gradient_image = ImageOps.colorize( gradientimage.resize((imgsize[0], imgsize[1])), color1, color2) image = api.RenderImage() image.SetAsImage(gradient_image.convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(GradientImageNode, "corenode_gradientimage")
self.NodeAddProp(p4) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') saturation_val = eval_info.EvaluateProperty('Saturation') brightness_val = eval_info.EvaluateProperty('Brightness') gamma_val = eval_info.EvaluateProperty('Gamma') threshold_val = eval_info.EvaluateProperty('Threshold') # Convert the current image data to an array # that we can use and greyscale it. im = ArrayFromImage(image1.GetImage()) gray_scale_img = cv2.equalizeHist(cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)) generated_specular_map = self.ComputeSpecularMap( gray_scale_img, saturation_val, brightness_val, gamma_val, threshold_val) image = api.RenderImage() image.SetAsImage(ArrayToImage(generated_specular_map).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ToSpecularMapNode, "corenode_tospecularmap")
return meta_info def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Amount", default=1, min_val=1, max_val=25, widget=api.SLIDER_WIDGET, label="Amount:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') sharpness_amount = eval_info.EvaluateProperty('Amount') image = api.RenderImage() enhancer = ImageEnhance.Sharpness(image1.GetImage()) image.SetAsImage(enhancer.enhance(sharpness_amount).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(SharpnessNode, "corenode_sharpness")
def __init__(self, _id): api.NodeBase.__init__(self, _id) @property def NodeMeta(self): meta_info = { "label": "Invert Alpha", "author": "Correct Syntax", "version": (1, 2, 0), "supported_app_version": (0, 5, 0), "category": "COLOR", "description": "Inverts the image alpha channel.", } return meta_info def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') image = api.RenderImage() image.SetAsImage(ImageChops.invert(image1.GetImage()).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(InvertAlphaNode, "corenode_invertalpha")
input_image_array = ArrayFromImage(input_image.GetImage()) if method == "Rectangle": output_image_array = input_image_array[y:y + height, x:x + width] else: # Create a blank mask mask = np.zeros(shape=input_image_array.data.shape, dtype=np.uint8) # Create the circle circle_mask_colour = cv2.circle(mask, tuple(center), radius, (255, 255, 255), -1) # Convert the mask to gray scale circle_mask = cv2.cvtColor(circle_mask_colour, cv2.COLOR_BGR2GRAY) # Combine the mask and image cropped_img = cv2.bitwise_and(input_image_array, input_image_array, mask=circle_mask) # Crop the circle circle_rect = cropped_img[center[1] - radius:center[1] + radius, center[0] - radius:center[0] + radius] output_image_array = circle_rect image = api.RenderImage() image.SetAsImage(ArrayToImage(output_image_array).convert("RGBA")) self.NodeSetThumb(image.GetImage().convert("RGBA")) return image api.RegisterNode(CropNode, "corenode_crop")
) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') opacity = eval_info.EvaluateProperty('Opacity') img = image1.GetImage().convert("RGBA") # Make correction for slider range of 1-100 image_opacity = (opacity * 0.01) # Only reduce the opacity if the value is acceptable if not image_opacity < 0 or not image_opacity > 1: alpha = ImageEnhance.Brightness( img.split()[-1]).enhance(image_opacity) img.putalpha(alpha) image = api.RenderImage() image.SetAsImage(img) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(OpacityNode, "corenode_opacity")
meta_info = { "label": "Alpha Composite", "author": "Correct Syntax", "version": (1, 2, 0), "supported_app_version": (0, 5, 0), "category": "BLEND", "description": "Creates a new image by interpolating between two input images, using a constant alpha.", } return meta_info def NodeInitParams(self): p1 = api.RenderImageParam('Image 1') p2 = api.RenderImageParam('Image 2') self.NodeAddParam(p1) self.NodeAddParam(p2) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image 1') image2 = eval_info.EvaluateParameter('Image 2') image = api.RenderImage() main_image = image1.GetImage() layer_image = ImageOps.fit(image2.GetImage(), main_image.size) image.SetAsImage(Image.alpha_composite(main_image, layer_image)) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(AlphaCompositeNode, "corenode_alphacomposite")
self.higher_threshold.SetIsVisible(True) self.RefreshPropertyPanel() def NodeEvaluation(self, eval_info): input_image = eval_info.EvaluateParameter("Image") method = eval_info.EvaluateProperty("Method") lower_threshold = eval_info.EvaluateProperty("Lower Threshold") higher_threshold = eval_info.EvaluateProperty("Higher Threshold") image = api.RenderImage() # Consider removing the Pillow method? if method == "Find Edges": img = input_image.GetImage().convert("L").filter( ImageFilter.FIND_EDGES) image.SetAsImage(img.convert("RGBA")) elif method == "Canny": input_image_array = ArrayFromImage(input_image.GetImage()) output_image_array = cv2.Canny(input_image_array, lower_threshold, higher_threshold) image.SetAsImage(ArrayToImage(output_image_array).convert("RGBA")) else: image.SetAsImage(input_image.GetImage()) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(EdgeDetectNode, "corenode_edgedetect")
def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Amount", default=1, min_val=1, max_val=50, widget=api.SLIDER_WIDGET, label="Amount:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') amount = eval_info.EvaluateProperty('Amount') image = api.RenderImage() enhancer = ImageEnhance.Brightness(image1.GetImage()) image.SetAsImage(enhancer.enhance(amount).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(BrightnessNode, "corenode_brightness")
def NodeInitProps(self): p = api.ChoiceProp( idname="Direction", default="Horizontal", label="Direction:", choices=["Horizontal", "Vertical"], ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') direction = eval_info.EvaluateProperty('Direction') image = api.RenderImage() if direction == 'Horizontal': image.SetAsImage(ImageOps.mirror(image1.GetImage())) else: image.SetAsImage(ImageOps.flip(image1.GetImage())) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(FlipNode, "corenode_flip")
api.NodeBase.__init__(self, _id) @property def NodeMeta(self): meta_info = { "label": "Invert", "author": "iwoithe", "version": (0, 0, 1), "supported_app_version": (0, 5, 0), "category": "FILTER", "description": "Inverts the image.", } return meta_info def NodeInitParams(self): image = api.RenderImageParam("Image") self.NodeAddParam(image) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') image = api.RenderImage() image.SetAsImage(ImageOps.invert(image1.GetImage().convert("RGB"))) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(InvertNode, "corenode_invert")
def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Amount", default=1, min_val=0, max_val=25, widget=api.SLIDER_WIDGET, label="Amount:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') amount = eval_info.EvaluateProperty('Amount') image = api.RenderImage() enhancer = ImageEnhance.Brightness(image1.GetImage()) image.SetAsImage(enhancer.enhance(amount).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ExampleCustomNode, "examplecustomnode_brightness")
} return meta_info def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Distance", default=1, min_val=0, max_val=50, widget=api.SLIDER_WIDGET, label="Distance:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') distance = eval_info.EvaluateProperty('Distance') image = api.RenderImage() image.SetAsImage(image1.GetImage().effect_spread(distance)) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(EffectSpreadNode, "corenode_effectspread")
self.NodeAddProp(self.layer_prop) def WidgetEventHook(self, idname, value): if idname in ["Layer"]: self.RefreshLayers() def RefreshLayers(self): # Update the thumbnail img = self.NodeEvaluation(EvalInfo(self)).GetImage() self.NodeSetThumb(img, force_refresh=True) self.RefreshPropertyPanel() # Update the property choices (only available for ChoiceProp) self.layer_prop.SetChoices(self.QueryBlenderImageLayers()) def NodeEvaluation(self, eval_info): layer = eval_info.EvaluateProperty('Layer') layer_path = self._layers[layer] image = api.RenderImage() image.SetAsOpenedImage(layer_path) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ImageFromBlenderNode, "corenode_imagefromblender")
elif blendmode == 'Multiply': img = ImageChops.multiply(main_image, layer_image) elif blendmode == 'Screen': img = ImageChops.screen(main_image, layer_image) elif blendmode == 'Difference': img = ImageChops.difference(main_image, layer_image) elif blendmode == 'Darker': img = ImageChops.darker(main_image, layer_image) elif blendmode == 'Lighter': img = ImageChops.lighter(main_image, layer_image) elif blendmode == 'Soft Light': img = ImageChops.soft_light(main_image, layer_image) elif blendmode == 'Hard Light': img = ImageChops.hard_light(main_image, layer_image) elif blendmode == 'Overlay': img = ImageChops.overlay(main_image, layer_image) image.SetAsImage(img) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(MixNode, "corenode_mix")
channel_img = image1.GetImage().getchannel(channel) if greyscale != True and channel != "A": if channel == "R": color = (255, 0, 0) elif channel == "G": color = (0, 255, 0) elif channel == "B": color = (0, 0, 255) final_img = ImageOps.colorize(channel_img, (0, 0, 0), color) elif channel == "A": inverted_img = ImageChops.invert(channel_img) new_img = Image.new("RGBA", inverted_img.size, (0, 0, 0, 0)) layer_image = ImageOps.fit(new_img, inverted_img.size) mask_image = ImageOps.fit(image1.GetImage(), inverted_img.size) final_img = Image.composite(inverted_img, layer_image, mask_image) else: final_img = channel_img image.SetAsImage(final_img.convert("RGBA")) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(GetChannelNode, "corenode_getchannel")
return meta_info def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Amount", default=1, min_val=1, max_val=25, widget=api.SLIDER_WIDGET, label="Amount:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') amount = eval_info.EvaluateProperty('Amount') image = api.RenderImage() enhancer = ImageEnhance.Color(image1.GetImage()) image.SetAsImage(enhancer.enhance(amount).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ColorBalanceNode, "corenode_colorbalance")
max_val=400, widget=api.SLIDER_WIDGET, label="Sigma:", ) self.size_prop = api.SizeProp(idname="Size", default=[255, 255], label="Image Size:") self.NodeAddProp(self.sigma_prop) self.NodeAddProp(self.size_prop) # def WidgetEventHook(self, idname, value): # if idname == "Sigma": # img = self.NodeEvaluation(EvalInfo(self)).GetImage() # self.NodeSetThumb(img, force_refresh=True) # self.RefreshPropertyPanel() def NodeEvaluation(self, eval_info): sigma = eval_info.EvaluateProperty('Sigma') imgsize = eval_info.EvaluateProperty('Size') image = api.RenderImage() image.SetAsImage( Image.effect_noise((imgsize[0], imgsize[1]), sigma).convert("RGBA")) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(NoiseImageNode, "corenode_noiseimage")
if kernel_shape == "Rectangle": kshape = cv2.MORPH_RECT elif kernel_shape == "Ellipse": kshape = cv2.MORPH_ELLIPSE elif kernel_shape == "Cross": kshape = cv2.MORPH_CROSS kernel_img = cv2.getStructuringElement(kshape, (kernel_size, kernel_size)) if operation == "Erode": output_img = cv2.erode(img, kernel_img, iterations=1) elif operation == "Dilate": output_img = cv2.dilate(img, kernel_img, iterations=1) elif operation == "Opening": output_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel_img) elif operation == "Closing": output_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel_img) elif operation == "Top Hat": output_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel_img) elif operation == "Black Hat": output_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel_img) image.SetAsImage(ArrayToImage(output_img).convert("RGBA")) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(DilateErodeNode, "corenode_dilateerode")
self.NodeAddProp(p1) self.NodeAddProp(p2) self.NodeAddProp(p3) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') saturation_val = eval_info.EvaluateProperty('Saturation') brightness_val = eval_info.EvaluateProperty('Brightness') gamma_val = eval_info.EvaluateProperty('Gamma') # Convert the current image data to an array # that we can use and greyscale it. im = ArrayFromImage(image1.GetImage()) gray_scale_img = cv2.equalizeHist(cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)) generated_roughness_map = self.ComputeRoughnessMap( gray_scale_img, saturation_val, brightness_val, gamma_val) image = api.RenderImage() image.SetAsImage(ArrayToImage(generated_roughness_map).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ToRoughnessMapNode, "corenode_toroughnessmap")
"Creates composite image by blending images using a transparency mask.", } return meta_info def NodeInitParams(self): p1 = api.RenderImageParam('Image 1') p2 = api.RenderImageParam('Image 2') p3 = api.RenderImageParam('Alpha Mask') self.NodeAddParam(p1) self.NodeAddParam(p2) self.NodeAddParam(p3) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image 1') image2 = eval_info.EvaluateParameter('Image 2') mask = eval_info.EvaluateParameter('Alpha Mask') image = api.RenderImage() main_image = image1.GetImage() layer_image = ImageOps.fit(image2.GetImage(), main_image.size) mask_image = ImageOps.fit(mask.GetImage(), main_image.size).convert('RGBA') image.SetAsImage(Image.composite(main_image, layer_image, mask_image)) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(CompositeNode, "corenode_composite")
def NodeInitProps(self): p = api.PositiveIntegerProp( idname="Amount", default=1, min_val=1, max_val=50, widget=api.SLIDER_WIDGET, label="Amount:", ) self.NodeAddProp(p) def NodeInitParams(self): p = api.RenderImageParam('Image') self.NodeAddParam(p) def NodeEvaluation(self, eval_info): image1 = eval_info.EvaluateParameter('Image') amount = eval_info.EvaluateProperty('Amount') image = api.RenderImage() enhancer = ImageEnhance.Contrast(image1.GetImage()) image.SetAsImage(enhancer.enhance(amount).convert('RGBA')) self.NodeSetThumb(image.GetImage()) return image api.RegisterNode(ContrastNode, "corenode_contrast")