コード例 #1
0
ファイル: test_attribute.py プロジェクト: CoffeeKing68/Layers
 def test_template_with_max_attribute_can_render(self):
     c1 = ColorLayer("color1",
                     content="Green",
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     c2 = ColorLayer("color2",
                     content="Blue",
                     left=NA(0),
                     width=NA(60),
                     top=SA("color1.bottom"),
                     height=NA(50))
     text = PTL("test",
                "Arial",
                15,
                "Black",
                content="Hello World",
                left=MinA(SA("color1.right"), SA("color2.right")),
                top=SA("color2.bottom"))
     bg = ColorBackgroundLayer("name", content="White")
     layers = [c1, c2, bg, text]
     temp = Template("temp",
                     *layers,
                     left=NA(0),
                     top=NA(0),
                     width=NA(300),
                     height=NA(300))
     temp.update_bounds()
     assert text["left"] == 60
コード例 #2
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]
コード例 #3
0
 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")
コード例 #4
0
ファイル: test_attribute.py プロジェクト: CoffeeKing68/Layers
    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")
コード例 #5
0
 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")
コード例 #6
0
    def test_can_have_templates_within_templates(self):
        pt = PointTextLayer("point_text_layer", content="Point Text Layer", font="Arial", size=35, color="Black",
                left=NA(0), top=NA(0))
        bg = ColorLayer("bg", content="Red", left=NA(0),
                width=SA("parent.width"), height=SA("parent.height"), top=NA(0))
        temp = Template("temp",  pt, bg, left=NA(0), right=SA("point_text_layer.right"),
                top=NA(0), height=NA(100))
        temp2 = Template("temp", temp, left=NA(0), right=SA("point_text_layer.right"),
                top=NA(0), height=NA(500))

        temp2.update_bounds()
コード例 #7
0
    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
コード例 #8
0
    def test_template_variable_get_set_correctly(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))
        assert pt.template == bg.template
        assert pt.parent == temp
        assert pt.template == temp2
        assert pt.template == temp.template
コード例 #9
0
 def test_point_text_layer_can_render_when_content_and_parent_is_set(self):
     l = PointTextLayer("layer",
                        "Arial",
                        12,
                        "Black",
                        content="hello world",
                        left=NA(30),
                        top=NA(45))
     temp = Template("temp",
                     l,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     temp.update_bounds()
     l.render()
     assert l.pre_render is not None
コード例 #10
0
 def test_can_update_y_bounds(self):
     layer = self.area_text_layer()
     temp = Template("temp",
                     layer,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     layer.y.update_bounds()
コード例 #11
0
    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")
コード例 #12
0
 def test_can_update_y_bounds_when_attributes_are_evaluatable_and_content_is_set(
         self):
     layer = self.point_text_layer()
     temp = Template("temp",
                     layer,
                     left=NA(0),
                     width=NA(50),
                     top=NA(0),
                     height=NA(50))
     layer.y.update_bounds()
コード例 #13
0
    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]
コード例 #14
0
ファイル: test_attribute.py プロジェクト: CoffeeKing68/Layers
    def test_can_make_negative_string_attribute(self):
        """Tests if negative SAs can be initialised
        and if the different conventions will produce the same result"""
        negative_str_attr_1 = SA("-title.right")
        negative_str_attr_2 = SA("title.right", True)

        # test_layer_1 and test_layer_2 will have same left value
        title = PTL("title",
                    "Arial",
                    15,
                    "Black",
                    content="Hello World",
                    left=NA(0),
                    top=NA(0))

        test_layer_1 = ColorLayer("test_layer_1",
                                  content="Blue",
                                  left=negative_str_attr_1,
                                  right=SA("parent.right"),
                                  top=SA("title.top"),
                                  height=NA(20))

        test_layer_2 = ColorLayer("test_layer_2",
                                  content="Green",
                                  left=negative_str_attr_2,
                                  right=SA("parent.right"),
                                  top=SA("test_layer_1.top"),
                                  height=NA(20))

        temp = Template("temp",
                        title,
                        test_layer_1,
                        test_layer_2,
                        left=NA(0),
                        width=NA(100),
                        top=NA(0),
                        height=NA(100))

        temp.update_bounds()
        assert test_layer_1["left"] == test_layer_2["left"]
コード例 #15
0
 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")
コード例 #16
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()
コード例 #17
0
    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()
コード例 #18
0
ファイル: test_attribute.py プロジェクト: CoffeeKing68/Layers
 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"
         )
コード例 #19
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")
コード例 #20
0
ファイル: mask.py プロジェクト: CoffeeKing68/Layers
        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")
コード例 #21
0
    def make(self, card):
        art_layers, llayers = self.layers(card)
        text_template = Template("text_temp",
                                 *llayers,
                                 left=NA(0),
                                 width=NA(self.WIDTH),
                                 top=NA(0),
                                 height=NA(self.HEIGHT))
        art_template = Template("art_temp",
                                *art_layers,
                                order=-5,
                                left=NA(0),
                                width=NA(self.WIDTH),
                                top=NA(0),
                                height=NA(self.HEIGHT))

        temp = Template("template",
                        text_template,
                        art_template,
                        left=NA(0),
                        width=NA(self.WIDTH),
                        top=NA(0),
                        height=NA(self.HEIGHT))

        # generic templating
        temp.mana_image_format = "svg"
        temp.resource_dir = self.RESOURCE_DIR

        # START setting content
        rules = self.getRules(card)

        temp.get_layer("rules").content = rules

        for name in temp.get_layer("text_temp").layers:
            layer = temp.get_layer(name)
            if layer.name in card:
                layer.content = card[layer.name]

        if card['flavor_name'] is not None:
            temp.get_layer('name').content = card['flavor_name']
            temp.get_layer('flavor_name').content = card['name']
            # card['name'], card['flavor_name'] = card['flavor_name'], card['name']

        if card["layout"] == "adventure":
            for cc in card['card_faces']:
                if "power" in cc:
                    creature = cc
                else:
                    adventure_card = cc

            temp.get_layer('name').content = creature['name']
            temp.get_layer('mana_cost').content = creature['mana_cost']
            temp.get_layer('type').content = creature['type_line']

            temp.get_layer(
                "adventure_rules").content = adventure_card['oracle_text']
            temp.get_layer(
                "adventure_type").content = adventure_card["type_line"]
            temp.get_layer("adventure_name").content = adventure_card["name"]
            temp.get_layer(
                "adventure_mana_cost").content = adventure_card["mana_cost"]
        elif card["layout"] == "split":
            temp.get_layer("name").content = card["card_faces"][0]["name"]
            temp.get_layer("type").content = card["card_faces"][0]["type_line"]
            temp.get_layer(
                "mana_cost").content = card["card_faces"][0]["mana_cost"]
            temp.get_layer(
                "rules").content = card["card_faces"][1]["oracle_text"]
            temp.get_layer("split_art_top"
                           ).content = card["card_faces"][0]["image_location"]
            temp.get_layer("split_art_bottom"
                           ).content = card["card_faces"][1]["image_location"]
            temp.get_layer(
                "split_name").content = card["card_faces"][1]["name"]
            temp.get_layer(
                "split_mana_cost").content = card["card_faces"][1]["mana_cost"]
            temp.get_layer(
                "split_type").content = card["card_faces"][0]["type_line"]
            temp.get_layer(
                "split_rules").content = card["card_faces"][0]["oracle_text"]

        # generic
        if "Creature" in card["type"]:
            temp.get_layer(
                "PT").content = f"{card['power']}/{card['toughness']}"

        number = card['number'].upper().zfill(3)
        count = int(card['count'])
        temp.get_layer("number").content = f"{number}/{count:03}"

        rarity = card["rarity"][0].upper()
        temp.get_layer("rarity").color = self.rarity_colors[rarity]
        temp.get_layer("rarity").content = rarity

        # RULES CONTENT
        # if rules != "":
        # else:
        #     temp.get_layer('rules').content = card[self.text_to_use]
        art_path = join(self.RESOURCE_DIR, "art", card['set'], f"{card['name']}_{card['id']}.jpg") \
            .replace("//", "__")
        # print(art_path)
        if card['image_location']:
            temp.get_layer("art").content = card['image_location']
        else:
            temp.get_layer("art").content = art_path if os.path.isfile(
                art_path) else None

        # generic
        temp.update_bounds()

        render_bg = temp.get_layer("art_temp").render()
        image = render_bg.clone()
        # if temp.get_layer("art").content is not None:
        render_text_shadow = temp.get_layer("text_temp").shadow(-4,
                                                                4,
                                                                sigma=2,
                                                                radius=4,
                                                                color="Black")
        image.composite(render_text_shadow, left=0, top=0)
        render_text = temp.get_layer("text_temp").render()
        image.composite(render_text, left=0, top=0)
        # END setting content

        # SAVING content
        # image.save(filename=join(SAVE_LOCATION, f"{card['name']}_{card['id']}.jpg").replace("//", "__"))
        # image.save(filename=join(SAVE_LOCATION, f"{card['name']}.jpg").replace("//", "__"))

        p = self.pdf.clone()
        p.composite(image, left=73, top=67)
        p.save(filename=join(self.PDF_SAVE_LOCATION,
                             f"{card['name']}_{card['id']}.pdf").replace(
                                 "//", "__"))
コード例 #22
0
    def layers(self, card):
        art_layers = {
            "bg":
            ColorBackgroundLayer("bg", content=Color(self.SHADOW_COLOR)),
            "art":
            FillIL("art",
                   order=-5,
                   XP50=NA(self.WIDTH / 2),
                   top=NA(self.B + self.TOP_OUTER_BORDER),
                   width=NA(self.B_ART_WIDTH),
                   height=NA(self.MIN_ART_HEIGHT)),
            "border":
            ImageLayer("border",
                       content=self.BORDER_PATH,
                       left=NA(0),
                       top=NA(0))
        }
        layers = {
            "dot":
            PTL("dot",
                self.RELAY,
                25,
                self.FC,
                content=".",
                left=AA(SA("set.right"), NA(self.SET_DOT_LANG_WIDTH)),
                ycenter=SA("set.ycenter")),
            "language":
            PTL("language",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                content="EN",
                left=AA(SA("dot.right"), NA(self.SET_DOT_LANG_WIDTH)),
                base=self.BOTTOM_BASE_INFO),
            "artist_brush":
            ResizeIL("artist_brush",
                     content=join(self.RESOURCE_DIR, "artist_brush_white.png"),
                     width=NA(20),
                     left=self.lmiddle,
                     height=SA("set.height"),
                     bottom=self.BOTTOM_BASE_INFO),
            "copyright":
            PTL("copyright",
                self.MPLANTIN,
                self.INFO_SIZE - 5,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                bottom=self.BOTTOM_BASE_INFO),
            "name":
            PTL("name",
                self.BELEREN,
                self.NAME_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=NA(70 + self.TOP_OUTER_BORDER)),
            "flavor_name":
            PTL("flavor_name",
                self.MPLANTIN_ITAL,
                self.FLAVOR_NAME_SIZE,
                self.FC,
                left=SA("name.left"),
                base=AA(SA("name.base"), NA(self.FLAVOR_NAME_SIZE + 4))),
            "PT":
            PTL("PT",
                self.BELEREN,
                self.PT_LOYAL_SIZE,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "loyalty":
            PTL("loyalty",
                self.BELEREN,
                self.PT_LOYAL_SIZE,
                self.FC,
                right=NA(self.WIDTH - self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "set":
            PTL("set",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=self.BOTTOM_BASE_INFO),
            "number":
            PTL("number",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=self.TOP_BASE_INFO),
            "rarity":
            PTL("rarity",
                self.RELAY,
                self.INFO_SIZE,
                self.FC,
                left=SA("artist_brush.left"),
                base=self.TOP_BASE_INFO),
            "artist":
            PTL("artist",
                self.BELEREN_SC,
                self.INFO_SIZE,
                self.FC,
                left=AA(SA("artist_brush.right"), NA(3)),
                base=self.BOTTOM_BASE_INFO),
            "mana_cost":
            ManaCost("mana_cost",
                     font=self.BELEREN,
                     font_size=self.NAME_SIZE,
                     font_color=self.FC,
                     right=NA(self.WIDTH - self.BORDER),
                     bottom=AA(SA("name.base"), NA(4))),
        }
        standard_rules = {
            "type":
            PTL("type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=AA(SA("rules.top"), NA(-10))),
            "rules":
            RulesText("rules",
                      self.MPLANTIN,
                      self.MPLANTIN_ITAL,
                      self.RULES_TEXT_SIZE,
                      self.FC,
                      self.RULES_TEXT_SIZE - 4,
                      left=NA(self.RULES_BORDER),
                      right=NA(self.WIDTH - self.RULES_BORDER),
                      base=AA(SA("rarity.cap"), NA(-6)))
        }
        split_text_layers = {
            "split_name":
            PTL("split_name",
                self.BELEREN,
                self.NAME_SIZE,
                self.FC,
                left=SA("name.left"),
                base=NA(self.SPLIT_CENTER + self.NAME_SIZE)),
            "split_mana_cost":
            ManaCost("split_mana_cost",
                     font=self.BELEREN,
                     font_size=self.NAME_SIZE,
                     font_color=self.FC,
                     right=SA("mana_cost.right"),
                     bottom=AA(SA("split_name.base"), NA(4))),
            "split_type":
            PTL("split_type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=SA("type.left"),
                base=AA(SA("split_rules.top"), NA(-10))),
            "split_rules":
            RulesText("split_rules",
                      self.MPLANTIN,
                      self.MPLANTIN_ITAL,
                      self.RULES_TEXT_SIZE,
                      self.FC,
                      self.RULES_TEXT_SIZE - 4,
                      left=SA("rules.left"),
                      right=SA("rules.right"),
                      base=AA(SA("split_name.cap"), NA(-6)))
        }

        split_kwargs = {
            "left": NA(0),
            "order": -5,
            "width": NA(self.B_ART_WIDTH),
            "height": NA(self.SPLIT_HEIGHT)
        }
        top_split_kwargs = {
            **split_kwargs, "YP50":
            NA((self.B + self.TOP_OUTER_BORDER + self.SPLIT_CENTER) / 2)
        }
        bottom_split_kwargs = {
            **split_kwargs, "YP50":
            NA((self.SPLIT_CENTER + self.SPLIT_END - 2) / 2)
        }

        split_art_layers = {
            "split_divider_top":
            GradL("split_divider_top",
                  start="RGBA(0,0,0,0.0)",
                  end=self.SHADOW_COLOR,
                  left=NA(0),
                  width=NA(self.WIDTH),
                  bottom=NA(self.SPLIT_CENTER),
                  height=NA(self.SPLIT_SHADOW_SIZE)),
            "split_divider_bottom":
            GradL("split_divider_bottom",
                  start=self.SHADOW_COLOR,
                  end="RGBA(0,0,0,0.0)",
                  left=NA(0),
                  width=NA(self.WIDTH),
                  top=NA(self.SPLIT_CENTER - 1),
                  height=NA(self.SPLIT_SHADOW_SIZE)),
            "split_art_top":
            Mask("split_art_top_mask",
                 FillIL("split_art_top", **top_split_kwargs),
                 **top_split_kwargs),
            "split_art_bottom":
            Mask("split_art_bottom_mask",
                 FillIL("split_art_bottom", **bottom_split_kwargs),
                 **bottom_split_kwargs)
        }
        adventure_rules = {
            "rules_box":
            Template(
                "rules_box",
                *[
                    RulesText("rules",
                              self.MPLANTIN,
                              self.MPLANTIN_ITAL,
                              self.RULES_TEXT_SIZE,
                              self.FC,
                              self.RULES_TEXT_SIZE - 4,
                              left=AA(SA("parent.xcenter"), NA(5)),
                              right=AA(SA("parent.right"),
                                       NA(self.RULES_BORDER, negative=True)),
                              ycenter=SA("template.ycenter")),
                    Template("adventure_box",
                             *[
                                 RulesText("adventure_rules",
                                           self.MPLANTIN,
                                           self.MPLANTIN_ITAL,
                                           self.RULES_TEXT_SIZE,
                                           self.FC,
                                           self.RULES_TEXT_SIZE - 4,
                                           left=NA(0),
                                           right=AA(SA("parent.width"),
                                                    NA(-5)),
                                           top=AA(SA("adventure_type.base"),
                                                  NA(6))),
                                 PTL("adventure_type",
                                     self.MPLANTIN,
                                     self.RULES_TEXT_SIZE + 3,
                                     self.FC,
                                     left=SA("adventure_name.left"),
                                     cap=AA(SA("adventure_name.base"), NA(6))),
                                 PTL("adventure_name",
                                     self.MPLANTIN,
                                     self.RULES_TEXT_SIZE + 5,
                                     self.FC,
                                     left=NA(0),
                                     cap=NA(3)),
                                 ManaCost("adventure_mana_cost",
                                          font=self.BELEREN,
                                          font_size=self.RULES_TEXT_SIZE,
                                          font_color=self.FC,
                                          right=SA("adventure_rules.right"),
                                          top=NA(0),
                                          mana_size=self.RULES_TEXT_SIZE),
                             ],
                             left=NA(self.RULES_BORDER),
                             right=AA(SA("rules.left"), NA(-10)),
                             ycenter=SA("template.ycenter"),
                             height=SA("null.height")),
                ],
                left=NA(0),
                width=NA(self.WIDTH),
                base=AA(
                    SA("self.height"), SA("rarity.cap"), NA(-6),
                    MA(SA("rules.bottom"),
                       SA("adventure_box.bottom"),
                       negative=True)),
                height=SA("template.height")),
            "type":
            PTL("type",
                self.BELEREN,
                self.TYPE_SIZE,
                self.FC,
                left=NA(self.BORDER),
                base=AA(SA("rules_box.top"),
                        MinA(SA("adventure_box.top"), SA("rules.top")),
                        NA(-10))),
        }
        if card['layout'] == 'adventure':
            layers = {**layers, **adventure_rules}
        elif card["layout"] == "split":
            layers = {**layers, **standard_rules, **split_text_layers}
            art_layers = {**art_layers, **split_art_layers}
        else:
            layers = {**layers, **standard_rules}

        return list(art_layers.values()), list(layers.values())
コード例 #23
0
 def test_can_make_template_layer(self):
     l = PointTextLayer("layer", "Arial", 12, "Black", content="hello world", left=NA(30), top=NA(45))
     temp = Template("temp", l, left=NA(0), width=NA(50), top=NA(0), height=NA(50))
コード例 #24
0
    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
コード例 #25
0
ファイル: adventure.py プロジェクト: CoffeeKing68/mtg4
 Template(
     "rules_box",
     *[
         RulesText("rules",
                   env("MPLANTIN"),
                   env("MPLANTIN_ITAL"),
                   env("RULES_TEXT_SIZE"),
                   env("FC"),
                   env("RULES_TEXT_SIZE") - 4,
                   left=AA(SA("parent.xcenter"), NA(5)),
                   right=AA(SA("parent.right"),
                            NA(env("RULES_BORDER"), negative=True)),
                   ycenter=SA("template.ycenter")),
         Template("adventure_box",
                  *[
                      RulesText("adventure_rules",
                                env("MPLANTIN"),
                                env("MPLANTIN_ITAL"),
                                env("RULES_TEXT_SIZE"),
                                env("FC"),
                                env("RULES_TEXT_SIZE") - 4,
                                left=NA(0),
                                right=AA(SA("parent.width"), NA(-5)),
                                top=AA(SA("adventure_type.base"), NA(6))),
                      PTL("adventure_type",
                          env("MPLANTIN"),
                          env("RULES_TEXT_SIZE") + 3,
                          env("FC"),
                          left=SA("adventure_name.left"),
                          cap=AA(SA("adventure_name.base"), NA(6))),
                      PTL("adventure_name",
                          env("MPLANTIN"),
                          env("RULES_TEXT_SIZE") + 5,
                          env("FC"),
                          left=NA(0),
                          cap=NA(3)),
                      ManaCost("adventure_mana_cost",
                               font=env("BELEREN"),
                               font_size=env("RULES_TEXT_SIZE"),
                               font_color=env("FC"),
                               right=SA("adventure_rules.right"),
                               top=NA(0),
                               mana_size=env("RULES_TEXT_SIZE")),
                  ],
                  left=NA(env("RULES_BORDER")),
                  right=AA(SA("rules.left"), NA(-10)),
                  ycenter=SA("template.ycenter"),
                  height=SA("null.height")),
         # ColorLayer("test_shape", content="red", left=SA("adventure_box.left"), right=SA("adventure_box.right"),
         #     top=SA("adventure_box.top"), bottom=SA("adventure_box.bottom"), order=-1),
         # ColorLayer("test_shape_2", content="green", left=SA("rules.left"), right=SA("rules.right"),
         #     top=SA("rules.top"), bottom=SA("rules.bottom"), order=-1),
         # ColorLayer("test_shape_2", content="blue", left=SA("parent.left"), right=SA("parent.right"),
         #     top=SA("parent.top"), height=NA(10), order=-1),
         # ColorBackgroundLayer("adventure_bg", content="blue"),
     ],
     left=NA(0),
     width=NA(env("WIDTH")),
     # bottom=DivA(AA(SA("self.height"), MA(SA("rules.height"), SA("adventure_box.height"))), NA(2)),
     bottom=AA(
         SA("self.height"), SA("rarity.cap"), NA(-10),
         MA(SA("rules.bottom"), SA("adventure_box.bottom"), negative=True)),
     height=SA("template.height")
     # height=MA(SA("rules.height"), SA("adventure_box.height"))
 ),
コード例 #26
0
ファイル: mardu.py プロジェクト: CoffeeKing68/mtg4
def main():
    RESOURCE_DIR = join(os.getcwd(), "resources")
    SETS = join(RESOURCE_DIR, "card_data", "sets.json")
    TEST_DIR = "test_images"

    MPLANTIN = join(RESOURCE_DIR, "fonts", "MPlantin.ttf")
    BELEREN_SC = join(RESOURCE_DIR, "fonts", "Beleren_small_caps.ttf")
    BELEREN = join(RESOURCE_DIR, "fonts", "Jace_Beleren_bold.ttf")
    MPLANTIN_BOLD = join(RESOURCE_DIR, "fonts", "MPlantin_bold.ttf")
    MPLANTIN_ITAL = join(RESOURCE_DIR, "fonts", "MPlantin_italic.ttf")
    RELAY = join(RESOURCE_DIR, "fonts", "Relay_medium.ttf")
    FC = "White"
    FLAVOR_SPLIT_COLOR = "RGBA(255, 255, 255, 0.6)"
    FLAVOR_SPLIT_OFFSET = 40

    if os.path.isfile(SETS):
        with open(SETS, "r") as f:
            sets = json.load(f)
    else:
        raise ValueError("sets.json not found.")

    myset = "WAR"
    # JSON = join(RESOURCE_DIR, "card_data", f"{myset}.json")
    # JSON = join(RESOURCE_DIR, "card_data", f"mardu_aristocrats_M20.json")
    # TOKENS = join(RESOURCE_DIR, "card_data", f"tokens.json")
    # ANGELS = join(RESOURCE_DIR, "card_data", f"mardu_angels_M20.json")
    JSON = join(RESOURCE_DIR, "set_data", f"{myset}.json")
    # SULTAI_FLASH = join(RESOURCE_DIR, "card_data", f"sultai_flash.json")

    SAVE_LOCATION = myset
    # SAVE_LOCATION = "sultai_flash"

    # JSON = SULTAI_FLASH
    # JSON = TOKENS
    """make directory in art"""
    # if not os.path.isdir(join(RESOURCE_DIR, "art", myset)): # dir does not exist
    #     os.mkdir(join(RESOURCE_DIR, "art", myset))
    """make directory in render dir"""
    if not os.path.isdir(join("test_images", "all_render",
                              SAVE_LOCATION)):  # dir does not exist
        os.mkdir(join("test_images", "all_render", SAVE_LOCATION))
    """load cards"""
    with open(JSON, "r") as f:
        cards = json.load(f)
    """load tokens"""
    # with open(TOKENS, "r") as f:
    #     tokens = json.load(f)

    BORDER = 45
    RULES_BORDER = 52
    HEIGHT = 1050
    WIDTH = 752
    SET_DOT_LANG_WIDTH = 5
    INFO_SIZE = 18
    # FONT_SIZE = 40
    NAME_SIZE = 38
    TYPE_SIZE = 33
    PT_LOYAL_SIZE = 40
    RULES_TEXT_SIZE = 25

    la = AA(MA(SA("language.right"), SA("number.right")), NA(3))
    lmiddle = AA(
        NA(WIDTH / 2),
        DivA(AA(SA("artist_brush.width"), NA(3), SA("artist.width")),
             NA(2),
             negative=True))

    art_layers = {
        "bg":
        ColorBackgroundLayer("bg", content=Color("Black")),
        "art":
        FillIL("art",
               order=-5,
               XP50=NA(WIDTH / 2),
               YP50=NA(HEIGHT / 2),
               width=NA(WIDTH),
               height=NA(HEIGHT)),
        "shadow1":
        ColorLayer("shadow1",
                   content="RGBA(0,0,0,0.4)",
                   left=NA(0),
                   width=NA(WIDTH),
                   top=NA(0),
                   bottom=SA("shadow2.top")),
        "shadow2":
        GradL("shadow2",
              start="RGBA(0,0,0,0.4)",
              end="RGBA(0,0,0,0.0)",
              left=NA(0),
              width=NA(WIDTH),
              top=SA("name.bottom"),
              height=NA(200)),
        "shadow3":
        GradL("shadow3",
              start="RGBA(0,0,0,0.0)",
              end="RGBA(0,0,0,0.7)",
              left=NA(0),
              width=NA(WIDTH),
              bottom=SA("shadow4.top"),
              top=AA(SA("type.cap"), NA(-150))),
        "shadow4":
        ColorLayer("shadow4",
                   content="RGBA(0,0,0,0.7)",
                   left=NA(0),
                   width=NA(WIDTH),
                   bottom=NA(HEIGHT + 1),
                   top=SA("rules.YP70"))
    }
    no_content_reset = {
        "dot":
        PTL("dot",
            RELAY,
            25,
            FC,
            content=".",
            left=AA(SA("set.right"), NA(SET_DOT_LANG_WIDTH)),
            ycenter=SA("set.ycenter")),
        "language":
        PTL("language",
            RELAY,
            INFO_SIZE,
            FC,
            content="EN",
            left=AA(SA("dot.right"), NA(SET_DOT_LANG_WIDTH)),
            base=NA(HEIGHT - BORDER)),
        "artist_brush":
        ResizeIL("artist_brush",
                 content=join(RESOURCE_DIR, "artist_brush_white.png"),
                 width=NA(20),
                 left=lmiddle,
                 height=SA("set.height"),
                 bottom=NA(HEIGHT - BORDER)),
        "copyright":
        PTL("copyright",
            MPLANTIN,
            INFO_SIZE - 5,
            FC,
            right=NA(WIDTH - BORDER),
            bottom=SA("set.bottom")),
    }
    layers = {
        "name":
        PTL("name", BELEREN, NAME_SIZE, FC, left=NA(BORDER), base=NA(80)),
        "type":
        PTL("type",
            BELEREN,
            TYPE_SIZE,
            FC,
            left=NA(BORDER),
            base=AA(SA("rules.top"), NA(-10))),
        "PT":
        PTL("PT",
            BELEREN,
            PT_LOYAL_SIZE,
            FC,
            right=NA(WIDTH - BORDER),
            base=SA("set.base")),
        "loyalty":
        PTL("loyalty",
            BELEREN,
            PT_LOYAL_SIZE,
            FC,
            right=NA(WIDTH - BORDER),
            base=SA("set.base")),
        "set":
        PTL("set",
            RELAY,
            INFO_SIZE,
            FC,
            left=NA(BORDER),
            base=NA(HEIGHT - BORDER)),
        "number":
        PTL("number",
            RELAY,
            INFO_SIZE,
            FC,
            left=NA(BORDER),
            base=AA(SA("set.cap"), NA(-3))),
        "rarity":
        PTL("rarity",
            RELAY,
            INFO_SIZE,
            FC,
            left=SA("artist_brush.left"),
            base=SA("number.base")),
        "artist":
        PTL("artist",
            BELEREN_SC,
            INFO_SIZE,
            FC,
            left=AA(SA("artist_brush.right"), NA(3)),
            base=SA("set.base")),
        "mana_cost":
        ManaCost("mana_cost",
                 font=BELEREN,
                 font_size=NAME_SIZE,
                 font_color=FC,
                 right=NA(WIDTH - BORDER),
                 bottom=AA(SA("name.base"), NA(4))),
        "rules":
        RulesText("rules",
                  MPLANTIN,
                  MPLANTIN_ITAL,
                  RULES_TEXT_SIZE,
                  FC,
                  RULES_TEXT_SIZE - 4,
                  left=NA(RULES_BORDER),
                  right=NA(WIDTH - RULES_BORDER),
                  bottom=AA(SA("PT.bottom"), NA(-PT_LOYAL_SIZE), NA(-5))),
        # "flavor_split": ColorLayer("flavor_split", left=NA(RULES_BORDER + FLAVOR_SPLIT_OFFSET),
        #     right=NA(WIDTH - RULES_BORDER - FLAVOR_SPLIT_OFFSET), height=NA(2),
        #     bottom=AA(SA("flavor.top"), NA(-5))),
        # "flavor": RulesText("flavor", MPLANTIN, MPLANTIN_ITAL, RULES_TEXT_SIZE, FC,
        #     RULES_TEXT_SIZE - 4, left=NA(RULES_BORDER), right=NA(WIDTH-RULES_BORDER),
        #     bottom=AA(SA("PT.bottom"), NA(-PT_LOYAL_SIZE), NA(-5))),
    }

    text_template = Template("text_temp",
                             *layers.values(),
                             *no_content_reset.values(),
                             left=NA(0),
                             width=NA(WIDTH),
                             top=NA(0),
                             height=NA(HEIGHT))
    art_template = Template("art_temp",
                            *art_layers.values(),
                            order=-5,
                            left=NA(0),
                            width=NA(WIDTH),
                            top=NA(0),
                            height=NA(HEIGHT))

    name = text_template.get_layer("name")

    with_art = list(os.listdir(join(RESOURCE_DIR, "art", myset)))
    cards = [c for c in cards if f"{c['name']}_{c['id']}.jpg" in with_art]
    cards = [c for c in cards if c['name'] == "Nicol Bolas, Dragon-God"]
    print(len(cards))

    # no_content_reset["copyright"].content = f"™ & © {datetime.now().year} Wizards of the Coast"
    # no_content_reset["copyright"].content = f"™ & © {datetime.now().year} WOTC"
    loga = math.ceil(math.log10(len(cards)))
    temp = Template("template",
                    text_template,
                    art_template,
                    left=NA(0),
                    width=NA(WIDTH),
                    top=NA(0),
                    height=NA(HEIGHT))
    temp.mana_image_format = "svg"
    temp.resource_dir = RESOURCE_DIR
    max_card_length = max(len(c['name']) for c in cards)
    row = f"| {{:0{loga}}}/{{:0{loga}}} | {{}} | {{}} | {{:07.3f}} |"
    total = 0

    for i, card in enumerate(sorted(cards, key=lambda x: x['name'])):
        start_time = time.time()
        for shadow in ["shadow3", "shadow4"]:
            l = temp.get_layer(shadow)
            l.pre_render = None

        reset_layers = list(layers) + ["art"]
        for name in reset_layers:
            layer = temp.get_layer(name)
            layer.unset_content_and_pre_render()
            # layer.content = None
            # layer.pre_render = None
            if layer.name in card:
                layer.content = card[layer.name]
        temp.get_layer("artist_brush").pre_shadow = None

        if "Creature" in card["types"]:
            layers["PT"].content = f"{card['power']}/{card['toughness']}"
        # print(card)
        # print(repr(temp.get_layer("name").content))
        count = 999
        sset = [s for s in sets if s['code'] == card['set']]
        if len(sset) == 1:
            count = sset[0]["count"]
        number = card['number'].upper().zfill(3)
        layers["number"].content = f"{number}/{count:03}"
        rarity_colors = {
            "M": "#D15003",
            "R": "#DFBD6C",
            "U": "#C8C8C8",
            "C": FC,
            "L": FC,
            "T": FC,
        }
        rarity = card["rarity"][0].upper()
        layers["rarity"].color = rarity_colors[rarity]
        layers["rarity"].content = rarity

        rules = ""
        text_to_use = "text"
        if card[text_to_use] is not None:
            rules = card[text_to_use]
        if card["flavor"] is not None:
            flavor = "\n".join(
                [f"<i>{f}</i>" for f in card['flavor'].split('\n')])
            if rules == "":
                rules = flavor
            else:
                rules += "\n" + flavor

        if rules != "":
            temp.get_layer("rules").content = rules
        art_path = join(RESOURCE_DIR, "art", card['set'], f"{card['name']}_{card['id']}.jpg") \
                .replace("//", "__")
        temp.get_layer("art").content = art_path if os.path.isfile(
            art_path) else None

        temp.update_bounds()
        render_bg = temp.get_layer("art_temp").render()
        image = render_bg.clone()
        if temp.get_layer("art").content is not None:
            render_text_shadow = temp.get_layer("text_temp").shadow(
                -4, 4, sigma=2, radius=4, color="Black")
            image.composite(render_text_shadow, left=0, top=0)
        render_text = temp.get_layer("text_temp").render()
        render_text.save(filename="test.png")
        image.composite(render_text, left=0, top=0)

        # xb = Bounds(start=BORDER - 10, end=WIDTH - BORDER + 10)
        # yb = Bounds(start=temp.get_layer("type")["top"] - 10,
        #     end=temp.get_layer("rules")['bottom'] + 10)
        # exp = render_bg.export_pixels(x=int(xb['start']), y=int(yb['start']),
        #     width=int(xb['full']), height=int(yb['full']))

        # with Image(width=int(xb['full']), height=int(yb['full']),
        #         background=Color("Transparent")) as blur_image:
        #     blur_image.import_pixels(width=int(xb['full']), height=int(yb['full']),
        #        channel_map="RGBA", storage="char", data=exp)
        #     with Image(width=blur_image.width, height=blur_image.height,
        #             background=Color("RGBA(0,0,0,0.2)")) as dark:
        #         blur_image.composite(dark, 0, 0)
        #     blur_image.blur(radius=10, sigma=5)
        #     with Image(width=blur_image.width, height=blur_image.height,
        #             background=Color("Black")) as mask:
        #         with Drawing() as ctx:
        #             ctx.fill_color = Color("White")
        #             ctx.rectangle(0, 0, width=mask.width,
        #                     height=mask.height, radius=15)
        #             ctx(mask)
        #         apply_mask(blur_image, mask)
        #     image.composite(blur_image, left=int(xb['start']), top=int(yb['start']))

        image.save(filename=join(
            "test_images", "all_render", f"{SAVE_LOCATION}",
            f"{card['name']}_{card['id']}.jpg").replace("//", "__"))
        # image.save(filename=join("test_images", "all_render", "Printing", f"{SAVE_LOCATION}", f"{card['name']}_{card['id']}.jpg").replace("//", "__"))
        # image.save(filename=join("test_images", "all_render", "Printing", f"{SAVE_LOCATION}", f"{card['name']}.jpg").replace("//", "__"))
        temp.unset_bounds_and_attributes()

        delta = time.time() - start_time
        total += delta
        if delta < .250:
            color = "green"
        elif delta < .500:
            color = "yellow"
        else:
            color = "red"
        print(f"\r{row}".format(
            i,
            len(cards) - 1,
            colored(f"{card['name']: <{max_card_length}}", color),
            colored(f"{delta:03.3f}", color), total))