def render_username(template_image):

        with WandImage.from_array(
            cv2.cvtColor(template_image, cv2.COLOR_BGRA2RGBA)
        ) as img:
            with WandDrawing() as context:
                context.font_size = BASE_FONT_SIZE

                if username:
                    context.fill_color = "#f7d676"
                    # Icon height doesnt match measurements exactly... HEIGHT/2 would be best for y
                    context.text(x=LOGO_WIDTH + 2, y=28, body=f"/u/{username}")
                else:
                    context.fill_color = "white"
                    context.fill_opacity = 0.8
                    context.text(x=LOGO_WIDTH + 2, y=28, body="• Temporary build")

                context(img)

            img.format = "png"

            img_buffer = np.asarray(bytearray(img.make_blob()), dtype=np.uint8)

            if img_buffer is not None:
                template_image = cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)

        return template_image
Example #2
0
    def render_background_rect(image_background):
        with WandImage.from_array(
                cv2.cvtColor(image_background, cv2.COLOR_BGRA2RGBA)) as img:
            with WandDrawing() as context:
                context.stroke_width = 1
                context.stroke_color = "rgba(255,255,255,1)"
                context.fill = TRAIT_BG
                context.fill_opacity = TRAIT_BG_OPACITY

                x1 = trait_hex_inradius
                y1 = text_box_y_top
                x2 = image_background.shape[1] - TRAIT_BG_STROKE_WIDTH / 2
                # padding is extra, but looks better
                y2 = text_box_y_top + text_box_height + TRAIT_BG_PADDING / 2

                context.rectangle(
                    left=int(x1),
                    top=int(y1),
                    width=int(x2 - x1),
                    height=int(y2 - y1),
                    radius=4,
                )

                context(img)

            img.format = "png"
            img_buffer = np.asarray(bytearray(img.make_blob()), dtype=np.uint8)

        if img_buffer is not None:
            return cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)
Example #3
0
    def render_count(image_base):

        count_x = icon_background_width + TRAIT_GAP
        count_height = int(text_box_height * COUNT_HEIGHT_PROPORTION)
        count_y = int(text_baseline_y - count_height / 2)
        count_width = COUNT_WIDTH

        with WandImage.from_array(cv2.cvtColor(image_base,
                                               cv2.COLOR_BGRA2RGBA)) as img:
            with WandDrawing() as context:
                context.fill_color = TRAIT_COUNT_BG

                context.rectangle(
                    left=count_x,
                    top=count_y,
                    width=count_width,
                    height=count_height,
                    radius=4,
                )

                font = WandFont(
                    os.path.join(
                        PATH_TO_ASSETS,
                        "fonts",
                        "Montserrat-Bold.ttf",
                    ),
                    color=Color("white"),
                )

                context(img)

                img.caption(
                    f"{trait_count}",
                    left=count_x,
                    top=count_y,
                    width=count_width,
                    height=count_height,
                    font=font,
                    gravity="center",
                )

                img.format = "png"

                img_buffer = np.asarray(bytearray(img.make_blob()),
                                        dtype=np.uint8)

        if img_buffer is not None:
            return cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)
Example #4
0
    def make_frame(self, streams):
        frame = WandImage(width=self.frame_d[0],background=Color('white'), height=self.frame_d[1])   

        for n, stream in enumerate(streams):
            img = WandImage(file=stream)
            x = config.photo_w * ((n >> 1) & 1)
            y = config.photo_h * (n & 1)
            frame.composite(img, left=x+18, top=y+18)
            drawing = WandDrawing()
#            drawing.font = '/home/pi/booth4/fonts/Steelworks.otf'
            drawing.font = '/home/pi/booth6/fonts/Vulturemotor.otf'
            drawing.font_size = 20
#            drawing.font_style = 'italic'
#            drawing.fill_color = Color('orange')
#            drawing.stroke_color = Color('brown')
            drawing.text(310, 660, 'The Mighty Booth') 
            drawing(frame)
        return frame
Example #5
0
    def render_trait_name_and_sets(image_base):
        text_x = icon_background_width + TRAIT_GAP + COUNT_WIDTH + TRAIT_GAP

        trait_text_y = text_baseline_y - FONT_BASELINE_GAP
        set_text_y = text_baseline_y + FONT_BASELINE_GAP + BASE_FONT_SIZE

        # draw trait name
        with WandImage.from_array(cv2.cvtColor(image_base,
                                               cv2.COLOR_BGRA2RGBA)) as img:
            with WandDrawing() as context:
                context.fill_color = "white"
                context.font_weight = 700
                context.font_size = BASE_FONT_SIZE
                context.text(x=text_x, y=trait_text_y, body=trait_name)

                context(img)

            for idx, trait_set in enumerate(trait_sets):
                width_per_count = 6  # just a guess

                is_last = idx == len(trait_sets) - 1
                set_x = text_x + idx * (width_per_count + TRAIT_SET_GAP +
                                        CARET_SIZE + TRAIT_SET_GAP)

                is_selected = (trait_set["min"] <= trait_count < (cast(
                    float, trait_set.get("max", float("inf")))))

                with WandDrawing() as context:
                    context.fill_color = "white"
                    context.font_size = BASE_FONT_SIZE
                    context.font_weight = 600

                    if is_selected:
                        context.fill_opacity = 1
                    else:
                        context.fill_opacity = 0.7

                    context.text(x=set_x,
                                 y=set_text_y,
                                 body=f"{trait_set['min']}")
                    context(img)

                if not is_last:
                    with WandDrawing() as context:

                        caret_x1 = set_x + TRAIT_GAP + width_per_count / 2
                        caret_x2 = caret_x1 + CARET_SIZE
                        caret_y1 = set_text_y - BASE_FONT_SIZE / 2 - CARET_SIZE / 4
                        caret_y2 = caret_y1 + CARET_SIZE

                        caret_pts = [
                            (caret_x1, caret_y1),
                            (caret_x2, caret_y1 + CARET_SIZE / 2),
                            (caret_x1, caret_y2),
                        ]

                        context.stroke_color = "white"
                        context.stroke_opacity = 0.6
                        context.fill_color = "transparent"
                        context.polyline(caret_pts)

                        context(img)

                img.format = "png"
                img_buffer = np.asarray(bytearray(img.make_blob()),
                                        dtype=np.uint8)

        if img_buffer is not None:
            return cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)
        def make_untrimmed_social_media_img():
            social_config = [
                {
                    "id": twitch_id,
                    "image_path": os.path.join(
                        PATH_TO_ASSETS, "socials", "twitch-transparent.png"
                    ),
                },
                {
                    "id": youtube_id,
                    "image_path": os.path.join(
                        PATH_TO_ASSETS, "socials", "youtube-22.png"
                    ),
                },
            ]

            # more space than we'll ever need; crop later
            social_base_image = np.zeros(
                (LOGO_HEIGHT, int(CARRY_IMAGE_WIDTH / 2), 4), dtype=np.uint8
            )

            SOCIAL_ROW_HEIGHT = 16
            SOCIAL_ICON_WIDTH = 22

            config_to_apply = [config for config in social_config if config["id"]]

            for idx, config in enumerate(config_to_apply):
                social_id = config["id"]
                image_path = config["image_path"]

                social_icon_image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)

                social_row_y = (SOCIAL_ROW_HEIGHT + 12) * idx

                overlay_transparent(
                    social_base_image, social_icon_image, 0, social_row_y
                )

                with WandImage.from_array(
                    cv2.cvtColor(social_base_image, cv2.COLOR_BGRA2RGBA)
                ) as img:
                    with WandDrawing() as context:
                        context.font_size = BASE_FONT_SIZE
                        context.fill_color = "white"

                        context.text(
                            x=SOCIAL_ICON_WIDTH + 2,
                            y=social_row_y + BASE_FONT_SIZE,
                            body=f"{social_id}",
                        )

                        context(img)

                    img.format = "png"

                    img_buffer = np.asarray(bytearray(img.make_blob()), dtype=np.uint8)

                    if img_buffer is not None:
                        social_base_image = cv2.imdecode(
                            img_buffer, cv2.IMREAD_UNCHANGED
                        )

            return social_base_image
Example #7
0
    def render_trait_name(image):

        trait_name_img = np.zeros(image.shape, dtype=np.uint8)

        icon_background_width = trait_style_background_img.shape[1]
        icon_background_height = trait_style_background_img.shape[0]

        trait_hex_inradius = icon_background_width / 2
        trait_hex_circumradius = icon_background_height / 2

        text_x = int(icon_background_width + TEXT_MARGIN_LEFT)
        text_centre_y = int(trait_hex_circumradius)

        (text_width, text_height) = get_text_dimensions(
            text=trait_name,
            font_size=BASE_FONT_SIZE,
        )

        pil_img = Image.fromarray(np.uint8(trait_name_img))

        # wanted to get text drawn with pillow; could not get working. Resorting to wand
        d = ImageDraw.Draw(pil_img)

        rect_x1 = int(trait_hex_inradius - TRAIT_BG_PADDING / 2)
        rect_y1 = int(text_centre_y - text_height / 2 - TRAIT_BG_PADDING / 2)
        rect_x2 = int(
            trait_hex_inradius
            + TEXT_MARGIN_LEFT
            + rect_x1
            + text_width
            + TRAIT_BG_PADDING
        )
        rect_y2 = int(rect_y1 + text_height + TRAIT_BG_PADDING)

        d.rectangle(
            [(rect_x1, rect_y1), (rect_x2, rect_y2)],
            fill=TRAIT_BG,
        )
        trait_name_img = np.asarray(pil_img)

        with WandImage.from_array(
            cv2.cvtColor(trait_name_img, cv2.COLOR_BGRA2RGBA)
        ) as img:
            with WandDrawing() as context:
                context.fill_color = "white"

                path_to_font = os.path.join(
                    PATH_TO_ASSETS,
                    "fonts",
                    "Heebo-Bold.ttf",
                )


                context.font = path_to_font

                context.font_size = BASE_FONT_SIZE

                text_y = int(text_centre_y + BASE_FONT_SIZE / 3)  # idk why 3

                context.text(text_x, text_y, trait_name)

                context(img)

            img.format = "png"

            img_buffer = np.asarray(bytearray(img.make_blob()), dtype=np.uint8)

        if img_buffer is not None:
            # # uint16 -> uint8 conversion (needed coming from wand)
            trait_name_img = cv2.imdecode(img_buffer, cv2.IMREAD_UNCHANGED)
            trait_name_img = cv2.convertScaleAbs(
                trait_name_img, alpha=(255.0 / 65535.0)
            )

            overlay_transparent(trait_name_img, image, 0, 0)

        return trait_name_img