def actualize_raster_image_node(): image_node.image, image_node.matrix = actualize( image_node.image, image_node.matrix, step_x=s_x, step_y=s_y) image_node.cache = None
def test_actualize_circle_step3_direct_black(self): """ Test for edge pixel error. Black Empty. :return: """ image = Image.new("RGBA", (256, 256), "black") draw = ImageDraw.Draw(image) draw.ellipse((100, 100, 150, 150), "white") for step in range(1, 20): transform = Matrix() actual, transform = actualize( image, transform, step_x=step, step_y=step, crop=False, inverted=True ) self.assertEqual(actual.getpixel((-1, -1)), 0) # Note: inverted flag not set. White edge pixel is correct. actual, transform = actualize(image, Matrix(), step_x=3, step_y=3, crop=False) self.assertEqual(actual.getpixel((-1, -1)), 255)
def test_actualize_circle_step3_direct_white(self): """ Test for edge pixel error. White empty. :return: """ image = Image.new("RGBA", (256, 256), "white") draw = ImageDraw.Draw(image) draw.ellipse((100, 100, 150, 150), "black") for step in range(1, 20): transform = Matrix() actual, transform = actualize( image, transform, step_x=step, step_y=step, crop=False ) self.assertEqual(actual.getpixel((-1, -1)), 255)
def process_image(self): if self.step_x is None: step = UNITS_PER_INCH / self.dpi self.step_x = step self.step_y = step from PIL import Image, ImageEnhance, ImageFilter, ImageOps from meerk40t.image.actualize import actualize from meerk40t.image.imagetools import dither image = self.image main_matrix = self.matrix r = self.red * 0.299 g = self.green * 0.587 b = self.blue * 0.114 v = self.lightness c = r + g + b try: c /= v r = r / c g = g / c b = b / c except ZeroDivisionError: pass if image.mode != "L": image = image.convert("RGB") image = image.convert("L", matrix=[r, g, b, 1.0]) if self.invert: image = image.point(lambda e: 255 - e) # Calculate device real step. step_x, step_y = self.step_x, self.step_y if ( main_matrix.a != step_x or main_matrix.b != 0.0 or main_matrix.c != 0.0 or main_matrix.d != step_y ): try: image, actualized_matrix = actualize( image, main_matrix, step_x=step_x, step_y=step_y, inverted=self.invert, ) except (MemoryError, DecompressionBombError): self.process_image_failed = True return else: actualized_matrix = Matrix(main_matrix) if self.invert: empty_mask = image.convert("L").point(lambda e: 0 if e == 0 else 255) else: empty_mask = image.convert("L").point(lambda e: 0 if e == 255 else 255) # Process operations. for op in self.operations: name = op["name"] if name == "crop": try: if op["enable"] and op["bounds"] is not None: crop = op["bounds"] left = int(crop[0]) upper = int(crop[1]) right = int(crop[2]) lower = int(crop[3]) image = image.crop((left, upper, right, lower)) except KeyError: pass elif name == "edge_enhance": try: if op["enable"]: if image.mode == "P": image = image.convert("L") image = image.filter(filter=ImageFilter.EDGE_ENHANCE) except KeyError: pass elif name == "auto_contrast": try: if op["enable"]: if image.mode not in ("RGB", "L"): # Auto-contrast raises NotImplementedError if P # Auto-contrast raises OSError if not RGB, L. image = image.convert("L") image = ImageOps.autocontrast(image, cutoff=op["cutoff"]) except KeyError: pass elif name == "tone": try: if op["enable"] and op["values"] is not None: if image.mode == "L": image = image.convert("P") tone_values = op["values"] if op["type"] == "spline": spline = ImageNode.spline(tone_values) else: tone_values = [q for q in tone_values if q is not None] spline = ImageNode.line(tone_values) if len(spline) < 256: spline.extend([255] * (256 - len(spline))) if len(spline) > 256: spline = spline[:256] image = image.point(spline) if image.mode != "L": image = image.convert("L") except KeyError: pass elif name == "contrast": try: if op["enable"]: if op["contrast"] is not None and op["brightness"] is not None: contrast = ImageEnhance.Contrast(image) c = (op["contrast"] + 128.0) / 128.0 image = contrast.enhance(c) brightness = ImageEnhance.Brightness(image) b = (op["brightness"] + 128.0) / 128.0 image = brightness.enhance(b) except KeyError: pass elif name == "gamma": try: if op["enable"] and op["factor"] is not None: if image.mode == "L": gamma_factor = float(op["factor"]) def crimp(px): px = int(round(px)) if px < 0: return 0 if px > 255: return 255 return px if gamma_factor == 0: gamma_lut = [0] * 256 else: gamma_lut = [ crimp(pow(i / 255, (1.0 / gamma_factor)) * 255) for i in range(256) ] image = image.point(gamma_lut) if image.mode != "L": image = image.convert("L") except KeyError: pass elif name == "unsharp_mask": try: if ( op["enable"] and op["percent"] is not None and op["radius"] is not None and op["threshold"] is not None ): unsharp = ImageFilter.UnsharpMask( radius=op["radius"], percent=op["percent"], threshold=op["threshold"], ) image = image.filter(unsharp) except (KeyError, ValueError): # Value error if wrong type of image. pass elif name == "halftone": try: if op["enable"]: image = RasterScripts.halftone( image, sample=op["sample"], angle=op["angle"], oversample=op["oversample"], black=op["black"], ) except KeyError: pass if empty_mask is not None: background = Image.new(image.mode, image.size, "white") background.paste(image, mask=empty_mask) image = background # Mask exists use it to remove any pixels that were pure reject. if self.dither and self.dither_type is not None: if self.dither_type != "Floyd-Steinberg": image = dither(image, self.dither_type) image = image.convert("1") inverted_main_matrix = Matrix(main_matrix).inverse() self.processed_matrix = actualized_matrix * inverted_main_matrix self.processed_image = image # self.matrix = actualized_matrix self.altered() self.process_image_failed = False