def test_idm_works_for_text_layer_without_content(self): bg = ColorBackgroundLayer("bg", content="White") # content is None layer = PointTextLayer("layer", "Arial", 12, "Black", left=NA(0), base=NA(40)) square = ColorLayer("sqr", content="Red", width=NA(20), height=NA(20), bottom=SA("layer.cap"), left=NA(25)) temp = Template("temp", layer, square, bg, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() temp.render().save( filename= "tests/images/test_idm_works_for_text_layer_without_content.png")
def test_can_order_layers_for_rendering(self): kwargs = { "left": SA("parent.left"), "right": SA("parent.right"), "top": SA("parent.top"), "bottom": SA("parent.bottom") } l1 = ColorLayer("layer_1", content="#FF0000", order=1, **kwargs) l2 = ColorLayer("layer_1", content="#00FF00", order=2, **kwargs) temp = Template("temp", l1, l2, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() green_above = temp.render() color_of_top_left_most_pixel = green_above.export_pixels(width=1, height=1) # RGBA, [1] is green assert color_of_top_left_most_pixel[:3] == [0, 255, 0] l1.order = 3 # move red above red_above = temp.render() color_of_top_left_most_pixel = red_above.export_pixels(width=1, height=1) assert color_of_top_left_most_pixel[:3] == [255, 0, 0]
def test_can_unset_attributes_evaluated_values(self): """Because the content of pt is changing per iteration, the left of square should change as well (top should change due to p in people).""" content_list = ["hello world", "people"] square_lefts = [] # stores left values per iteration square_tops = [] pt = PTL("pt", "Arial", 15, "Black", left=NA(0), top=NA(0)) square = ColorLayer("square", content="Red", left=AA(SA("pt.right")), top=SA("pt.bottom"), width=NA(20), height=NA(20)) bg = ColorBackgroundLayer("bg", content="White") temp = Template("temp", pt, square, bg, left=NA(0), top=NA(0), height=NA(100), width=NA(100)) for i, content in enumerate(content_list): pt.pre_render = None pt.content = content temp.unset_bounds_and_attributes() temp.update_bounds() temp.render().save( filename= f"tests/images/{i}_test_can_unset_attributes_evaluated_values.png" ) square_lefts.append(temp.get_layer("square")["left"]) square_tops.append(temp.get_layer("square")["top"]) assert square_lefts[0] != square_lefts[1] assert square_tops[0] != square_tops[1]
def test_can_render_shadow(self): pt = PTL("pt", "Arial", 15, "Black", content="PT", left=NA(0), top=NA(0)) pt2 = PTL("pt2", "Arial", 15, "Black", content="PT2", left=NA(0), top=AA(SA("pt.bottom"), NA(5))) bg = ColorBackgroundLayer("bg", content="White") temp = Template("temp", pt, pt2, bg, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() image = temp.render() image.save(filename="tests/images/test_can_render_shadow_1.png") shadow = pt2.shadow(2, 2, radius=4, sigma=2) image.composite(shadow, 0, 0) image.save(filename="tests/images/test_can_render_shadow_2.png")
def test_can_render_color_overlay(self): pt = PTL("pt", "Arial", 15, "Black", content="PT", left=NA(0), top=NA(0)) pt2 = PTL("pt2", "Arial", 15, "Black", content="PT2", left=NA(0), top=AA(SA("pt.bottom"), NA(5))) bg = ColorBackgroundLayer("bg", content="Red") temp = Template("temp", pt, pt2, bg, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() image = temp.render() image.save(filename="tests/images/test_can_render_color_overlay_1.png") overlay = pt2.color_overlay("Blue") image.composite(overlay, int(pt2["left"]), int(pt2["top"])) image.save(filename="tests/images/test_can_render_color_overlay_2.png")
def test_template_with_add_attribute_can_render(self): title = PTL("title", "Arial", 15, "Black", content="Hello World", left=NA(0), top=NA(0)) sub_title = PTL("sub_title", "Arial", 15, "Black", content="Bottom Text", left=NA(10), bottom=AA(SA("template.height"), NA(45, negative=True))) bg = ColorBackgroundLayer("bg", content="White") temp = Template("temp", title, sub_title, bg, left=NA(0), top=NA(0), width=NA(200), height=NA(200)) temp.update_bounds() image = temp.render() image.save( filename= f"tests/images/test_template_with_add_attribute_can_render.jpg")
def test_layers_passed_in_first_without_order_are_rendered_first( self, save_images): kwargs = { "left": SA("parent.left"), "right": SA("parent.right"), "top": SA("parent.top"), "bottom": SA("parent.bottom") } l1 = ColorLayer("layer_1", content="#FF0000", **kwargs) # red l2 = ColorLayer("layer_1", content="#00FF00", **kwargs) # green # l1 is first, is rendered first; therefore l2 (green) should be on top temp = Template("temp", l1, l2, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() green_above = temp.render() color_of_top_left_most_pixel = green_above.export_pixels(width=1, height=1) assert color_of_top_left_most_pixel[:3] == [0, 255, 0] # RGBA, [1] is green # remake template, now l2 is first, l1 rendered last temp = Template("temp", l2, l1, left=NA(0), width=NA(50), top=NA(0), height=NA(50)) temp.update_bounds() red_above = temp.render() color_of_top_left_most_pixel = red_above.export_pixels(width=1, height=1) assert color_of_top_left_most_pixel[:3] == [255, 0, 0] if save_images: green_above.save(filename="tests/images/green_above.png") red_above.save(filename="tests/images/red_above.png")
def test_setting_base_on_ptl_is_same_as_drawing_text(self): width = 100 text = "Hpqrs" left = 0 base = 20 median = 40 median_offset_for_font_size_12 = 6 bg_color = "White" bg = ColorBackgroundLayer("bg", content=bg_color) l = PointTextLayer("l", "Arial", 12, "Black", content=text, left=NA(left), base=NA(base)) l2 = PointTextLayer("l2", "Arial", 12, "Black", content=text, left=NA(left), median=NA(median)) temp = Template("temp", l, l2, bg, left=NA(0), right=NA(width), top=NA(0), bottom=NA(width)) temp.update_bounds() img = temp.render() img.save( filename= "tests/images/test_setting_base_on_ptl_is_same_as_drawing_text.png" ) with nested( Image(width=width, height=width, background=Color(bg_color)), Drawing()) as (img2, draw): draw.font = l.font draw.font_size = l.size draw.text(left, base, text) draw.text(left, median + median_offset_for_font_size_12, text) draw(img2) img2.save( filename= "tests/images/test_setting_base_on_ptl_is_same_as_drawing_text_2.png" ) location, diff = img.similarity(img2, metric="absolute") assert diff == 0
def test_can_get_mean_indepth_font_metrics_for_ptl(self): bg = ColorBackgroundLayer("bg", content="White") l = PointTextLayer("l", "Arial", 12, "Black", content="Hpqrs", left=NA(0), base=NA(20)) l2 = PointTextLayer("l2", "Arial", 12, "Black", content="e", left=NA(10), median=NA(50)) # l3 = PointTextLayer("l3", "Arial", 12, "Black", content="l", left=NA(20), descender=NA(50)) l4 = PointTextLayer("l4", "Arial", 12, "Black", content="l", left=NA(30), cap=NA(50)) # l5 = PointTextLayer("l5", "Arial", 12, "Black", content="o", left=NA(40), ascender=NA(50)) temp = Template( "temp", l, l2, bg, left=NA(0), # temp = Template("temp", l, l2, l3, l4, l5, left=NA(0), # right=SA("l5.right"), top=NA(0), bottom=SA("l5.bottom")) right=SA("l.right"), top=NA(0), bottom=SA("l.bottom")) temp.update_bounds() temp.render().save( filename= "tests/images/test_can_get_mean_indepth_font_metrics_for_ptl.png")
def test_template_configurations_dont_change_output(self): pt = PointTextLayer("ptl", "Arial", 10, "Black", content="Hello", left=NA(0), top=NA(0)) pt2 = PointTextLayer("ptl2", "Arial", 10, "Black", content="foobar", left=NA(10), top=NA(10)) pt3 = PointTextLayer("ptl3", "Arial", 10, "Black", content="Garlic", left=NA(20), top=NA(20)) temp1 = Template("temp1", pt, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp23 = Template("temp23", pt2, pt3, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp123 = Template("temp123", temp1, temp23, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp4 = Template("temp", pt, pt2, pt3, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp123.update_bounds() image123 = temp123.render() image123.save(filename="tests/images/test_template_configurations_dont_change_output_1.png") temp4.update_bounds() image4 = temp4.render() image4.save(filename="tests/images/test_template_configurations_dont_change_output_2.png") location, diff = image123.similarity(image4, metric="absolute") assert diff == 0
def test_template_can_render_boundary(self): pt = PointTextLayer("pt", "Arial", 15, "Black", content="Hello World", left=NA(0), top=NA(0)) square = ColorLayer("square", content="Orange", left=NA(20), top=NA(20), height=NA(20), width=NA(20)) bg = ColorBackgroundLayer("bg", content="None") temp = Template("temp", pt, square, bg, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp.update_bounds() boundary = temp.render_boundary() # boundary.save(filename="tests/images/test_template_can_render_boundary_b.png") image = temp.render()
def test_this_configuration_can_render(self): pt = PointTextLayer("ptl", "Arial", 15, "Black", content="Hello World", left=AA(SA("parent.left"), NA(5)), top=SA("parent.top")) bg = ColorBackgroundLayer("bg", content="Green") temp = Template("temp", pt, bg, left=NA(10), right=SA("ptl.right"), top=SA("parent.top"), height=NA(100)) temp2 = Template("temp2", temp, left=NA(0), right=NA(100), top=NA(0), height=NA(100)) temp2.update_bounds() image = temp2.render()
def test_exception_raised_if_no_existant_layer_is_referenced_in_SA(self): with pytest.raises(LayerDoesNotExistError): pt = PTL("test", "Arial", 15, "Black", content="Hello", left=NA(0), top=NA(0)) sq = ColorLayer("square", content="Red", left=NA(0), top=SA("doesnotexist.bottom"), width=NA(20), height=NA(20)) bg = ColorBackgroundLayer("bg", content="Green") bg2 = ColorBackgroundLayer("bg2", content="White") temp2 = Template("temp2", sq, bg, left=NA(0), width=NA(25), top=NA(0), height=NA(25)) temp = Template("temp", pt, bg2, temp2, left=NA(0), width=NA(100), top=NA(0), height=NA(100)) temp.update_bounds() # from pprint import pprint # pprint(temp.get_layer("temp2").__dict__) temp.render().save( filename= "tests/images/test_exception_raised_if_no_existant_layer_is_referenced_in_SA.png" )
image = Image(width=int(self["width"]), height=int(self["height"])) for layer in sorted(self.layers, key=lambda l: l.order): if layer.content is not None or isinstance(layer, Template): img = layer.render(fresh) if img is not None: image.composite(img, left=int(layer["left"] - self["left"]), top=int(layer["top"]- self["top"])) return image if __name__ == "__main__": # color = ColorLayer("color", content="Red", left=AA(SA('-parent.left'), NA(100)), width=NA(300), # top=AA(SA('-parent.top'), NA(100)), height=NA(500)) # bg = ColorBackgroundLayer("bg", content="White") # mask_bg = ColorBackgroundLayer("bg", content="Green") # mask = Template("mask", color, mask_bg, left=NA( # 200), width=NA(200), top=NA(100), height=NA(300)) # temp = Template("main", mask, bg, left=NA( # 0), width=NA(500), top=NA(0), height=NA(700)) color2 = ColorLayer("color", content="Red", left=NA(100), width=NA(300), top=NA(100), height=NA(500)) bg2 = ColorBackgroundLayer("bg", content="White") mask_bg2 = ColorBackgroundLayer("bg", content="Green") mask2 = Mask("mask", color2, mask_bg2, left=NA(200), width=NA(200), top=NA(100), height=NA(300)) temp2 = Template("main", mask2, bg2, left=NA(0), width=NA(500), top=NA(0), height=NA(700)) temp2.update_bounds() image = temp2.render() image.save(filename="test.png")