def GenerateImage(self, date: str, itemShop: dict):
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        try:
            featured = itemShop["featured"]["entries"]
            daily = itemShop["daily"]["entries"]

            if (len(featured) <= 0) or (len(daily) <= 0):
                raise Exception(
                    f"Featured: {len(featured)}, Daily: {len(daily)}")

            if (len(featured) >= 1):
                width = 6
                height = max(ceil(len(featured) / 3), ceil(len(daily) / 3))

                rowsDaily = 3
                rowsFeatured = 3

                dailyStartX = ((340 * 3))

            if (len(featured) >= 18):
                width = 9
                height = max(ceil(len(featured) / 6), ceil(len(daily) / 6))

                rowsDaily = 3
                rowsFeatured = 6

                dailyStartX = ((340 * 6))

            if (len(featured) >= 18) and (len(daily) >= 18):
                width = 12
                height = max(ceil(len(featured) / 6), ceil(len(daily) / 6))

                rowsDaily = 6
                rowsFeatured = 6

                dailyStartX = ((340 * 6) + 100)

        except Exception as e:
            log.critical(
                f"Failed to parse Item Shop Featured and Daily items, {e}")
            return False

        # Determine the max amount of rows required for the current
        # Item Shop when there are 3 columns for both Featured and Daily.
        # This allows us to determine the image height.
        # rows = max(ceil(len(featured) / 3), ceil(len(daily) / 3))
        shopImage = Image.new("RGB",
                              (((340 * width) - 30), (530 * height) + 350))

        try:
            background = ImageUtil.Open(self, "background.png").convert("RGBA")
            background = ImageUtil.RatioResize(self, background,
                                               shopImage.width,
                                               shopImage.height)
            shopImage.paste(
                background,
                ImageUtil.CenterX(self, background.width, shopImage.width))
        except FileNotFoundError:
            log.warn("Failed to open background.png, defaulting to dark gray")
            shopImage.paste((18, 18, 18),
                            [0, 0, shopImage.size[0], shopImage.size[1]])

        logo = ImageUtil.Open(self, "logo.png").convert("RGBA")
        logo = ImageUtil.RatioResize(self, logo, 0, 210)
        shopImage.paste(
            logo, ImageUtil.CenterX(self, logo.width, shopImage.width, 20),
            logo)

        canvas = ImageDraw.Draw(shopImage)
        font = ImageUtil.Font(self, 48)
        textWidth, _ = font.getsize(date)
        canvas.text(
            ImageUtil.CenterX(self, textWidth, shopImage.width, 255),
            date,
            (255, 255, 255),
            font=font,
        )
        canvas.text((20, 255), "Destacados", (255, 255, 255), font=font)
        textWidth, _ = font.getsize("Daily")
        canvas.text(
            (shopImage.width - (textWidth + 30), 255),
            "Diario",
            (255, 255, 255),
            font=font,
        )

        # Track grid position
        i = 0

        for item in featured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (20 + ((i % rowsFeatured) * (310 + 20))),
                        (350 + ((i // rowsFeatured) * (510 + 20))),
                    ),
                    card,
                )

                i += 1

        # Reset grid position
        i = 0

        for item in daily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (dailyStartX + ((i % rowsDaily) * (310 + 20))),
                        (350 + ((i // rowsDaily) * (510 + 20))),
                    ),
                    card,
                )

                i += 1

        try:
            shopImage.save("itemshop.png")
            log.info("Imagen generada de la Tienda de Objetos")

            return True
        except Exception as e:
            log.critical(f"Failed to save Item Shop image, {e}")
Exemplo n.º 2
0
    def GenerateImage(self, date: str, itemShop: dict):
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        try:
            featured = itemShop["featured"]
            daily = itemShop["daily"]

            # Ensure both Featured and Daily have at least 1 item
            if (len(featured) <= 0) or (len(daily) <= 0):
                raise Exception(
                    f"Featured: {len(featured)}, Daily: {len(daily)}")
        except Exception as e:
            log.critical(
                f"Failed to parse Item Shop Featured and Daily items, {e}")

            return False

        # Determine the max amount of rows required for the current
        # Item Shop when there are 3 columns for both Featured and Daily.
        # This allows us to determine the image height.
        featured_length = (FEATURED_COLUMNS * CARD_WIDTH) + (
            (FEATURED_COLUMNS - 1) * CARD_OFFSET)
        daily_length = (DAILY_COLUMNS * CARD_WIDTH) + (
            (DAILY_COLUMNS - 1) * CARD_OFFSET)
        columns_length = featured_length + daily_length
        rows = max(ceil(len(featured) / FEATURED_COLUMNS),
                   ceil(len(daily) / DAILY_COLUMNS))
        shopImage = Image.new(
            IMAGE_LOAD_TYPE,
            (columns_length + SECTION_SPACING,
             ((CARD_HEIGHT * rows) + 340) + (rows - 1) * CARD_OFFSET +
             logo_footer_offset + logo_footer_height))

        try:
            background = ImageUtil.Open(self, "background.png")
            background = ImageUtil.RatioResize(self, background,
                                               shopImage.width,
                                               shopImage.height)
            shopImage.paste(
                background,
                ImageUtil.CenterX(self, background.width, shopImage.width))
        except FileNotFoundError:
            log.warning(
                "Failed to open background.png, defaulting to dark gray")
            shopImage.paste((18, 18, 18),
                            [0, 0, shopImage.size[0], shopImage.size[1]])

        logo = ImageUtil.Open(self, logo_header_name)
        logo = ImageUtil.RatioResize(self, logo, 0, logo_header_height)
        shopImage.paste(
            logo, ImageUtil.CenterX(self, logo.width, shopImage.width, 20),
            logo)

        logo_footer = ImageUtil.Open(self, logo_footer_name)
        logo_footer = ImageUtil.RatioResize(self, logo_footer, 0,
                                            logo_footer_height)
        shopImage.paste(
            logo_footer,
            ImageUtil.CenterX(self, logo_footer.width, shopImage.width,
                              shopImage.height - logo_footer.height - 20),
            logo_footer)

        canvas = ImageDraw.Draw(shopImage)
        font = ImageUtil.Font(self, 58)
        textWidth, _ = font.getsize(date.upper())
        canvas.text(
            ImageUtil.CenterX(self, textWidth, shopImage.width, 255),
            date.upper(),
            (255, 255, 255),
            font=font,
        )
        canvas.text((LEFT_OFFSET, 255),
                    "IN EVIDENZA", (255, 255, 255),
                    font=font)
        textWidth, _ = font.getsize("GIORNALIERO")
        canvas.text(
            (shopImage.width - (textWidth + LEFT_OFFSET), 255),
            "GIORNALIERO",
            (255, 255, 255),
            font=font,
        )

        # Track grid position
        i = 0

        for item in featured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (LEFT_OFFSET + ((i % FEATURED_COLUMNS) *
                                        (card.width + CARD_OFFSET))),
                        (LEADING_OFFSET + ((i // FEATURED_COLUMNS) *
                                           (card.height + CARD_OFFSET))),
                    ),
                    card,
                )

                i += 1

        # Reset grid position
        i = 0
        DAILY_SPACING = SECTION_SPACING + featured_length - LEFT_OFFSET

        for item in daily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (DAILY_SPACING + ((i % DAILY_COLUMNS) *
                                          (card.width + CARD_OFFSET))),
                        (LEADING_OFFSET + ((i // DAILY_COLUMNS) *
                                           (card.height + CARD_OFFSET))),
                    ),
                    card,
                )

                i += 1

        try:
            shopImage.save(image_saved_name)
            log.info("Generated Item Shop image")

            return True
        except Exception as e:
            log.critical(f"Failed to save Item Shop image, {e}")
    def GenerateCard(self, item: dict):
        """Return the card image for the provided Fortnite Item Shop item."""

        try:
            name = item["items"][0]["name"]
            rarity = item["items"][0]["rarity"]["value"]
            category = item["items"][0]["type"]["value"]
            price = item["finalPrice"]
            if item["items"][0]["images"]["featured"] is not None:
                icon = item["items"][0]["images"]["featured"]
            else:
                icon = item["items"][0]["images"]["icon"]
        except Exception as e:
            log.error(f"Failed to parse item {name}, {e}")

            return

        if rarity == "frozen":
            blendColor = (148, 223, 255)
        elif rarity == "lava":
            blendColor = (234, 141, 35)
        elif rarity == "legendary":
            blendColor = (211, 120, 65)
        elif rarity == "dark":
            blendColor = (251, 34, 223)
        elif rarity == "starwars":
            blendColor = (231, 196, 19)
        elif rarity == "marvel":
            blendColor = (197, 51, 52)
        elif rarity == "slurp":
            blendColor = (0, 242, 213)
        elif rarity == "dc":
            blendColor = (84, 117, 199)
        elif rarity == "icon":
            blendColor = (54, 183, 183)
        elif rarity == "shadow":
            blendColor = (113, 113, 113)
        elif rarity == "epic":
            blendColor = (177, 91, 226)
        elif rarity == "rare":
            blendColor = (73, 172, 242)
        elif rarity == "uncommon":
            blendColor = (96, 170, 58)
        elif rarity == "common":
            blendColor = (190, 190, 190)
        elif rarity == "gaminglegends":
            blendColor = (42, 0, 168)
        else:
            blendColor = (255, 255, 255)

        card = Image.new("RGBA", (300, 545))

        try:
            layer = ImageUtil.Open(
                self, f"shopitem_background_{rarity}.png").convert("RGBA")
        except FileNotFoundError:
            log.warn(
                f"Failed to open shopitem_background_{rarity}.png, defaulted to Common"
            )
            layer = ImageUtil.Open(self, "shopitem_background_common.png")

        card.paste(layer)

        icon = ImageUtil.Download(self, icon).convert("RGBA")
        if (category == "outfit") or (category == "emote"):
            icon = ImageUtil.RatioResize(self, icon, 285, 365)
        elif category == "wrap":
            icon = ImageUtil.RatioResize(self, icon, 230, 310)
        else:
            icon = ImageUtil.RatioResize(self, icon, 310, 390)
        if (category == "outfit") or (category == "emote"):
            card.paste(icon, ImageUtil.CenterX(self, icon.width, card.width),
                       icon)
        else:
            card.paste(icon, ImageUtil.CenterX(self, icon.width, card.width,
                                               15), icon)

        if len(item["items"]) > 1:
            # Track grid position
            i = 0

            # Start at position 1 in items array
            for extra in item["items"][1:]:
                try:
                    extraRarity = extra["rarity"]["value"]
                    extraIcon = extra["images"]["smallIcon"]
                except Exception as e:
                    log.error(f"Failed to parse item {name}, {e}")

                    return

                try:
                    layer = ImageUtil.Open(
                        self, f"box_bottom_{extraRarity}.png").convert("RGBA")
                except FileNotFoundError:
                    log.warn(
                        f"Failed to open box_bottom_{extraRarity}.png, defaulted to Common"
                    )
                    layer = ImageUtil.Open(self, "box_bottom_common.png")

                card.paste(
                    layer,
                    (
                        (card.width - (layer.width + 9)),
                        (9 + ((i // 1) * (layer.height))),
                    ),
                )

                extraIcon = ImageUtil.Download(self, extraIcon).convert("RGBA")
                extraIcon = ImageUtil.RatioResize(self, extraIcon, 75, 75)

                card.paste(
                    extraIcon,
                    (
                        (card.width - (layer.width + 9)),
                        (9 + ((i // 1) * (extraIcon.height))),
                    ),
                    extraIcon,
                )

                try:
                    layer = ImageUtil.Open(self,
                                           f"box_faceplate_{extraRarity}.png")
                except FileNotFoundError:
                    log.warn(
                        f"Failed to open box_faceplate_{extraRarity}.png, defaulted to Common"
                    )
                    layer = ImageUtil.Open(self, "box_faceplate_common.png")

                card.paste(
                    layer,
                    (
                        (card.width - (layer.width + 9)),
                        (9 + ((i // 1) * (layer.height))),
                    ),
                    layer,
                )

                i += 1

        try:
            layer = ImageUtil.Open(
                self, f"shopitem_card_{rarity}.png").convert("RGBA")
        except FileNotFoundError:
            log.warn(
                f"Failed to open shopitem_card_{rarity}.png, defaulted to Common"
            )
            layer = ImageUtil.Open(self, "cshopitem_card_common.png")

        card.paste(layer, layer)

        card.paste(layer, layer)

        canvas = ImageDraw.Draw(card)

        font = ImageUtil.Font(self, 33)
        textWidth, _ = font.getsize(f"{category} {rarity}")
        canvas.text(
            ImageUtil.CenterX(self, textWidth, card.width, 385),
            f"",
            blendColor,
            font=font,
        )

        vbucks = ImageUtil.Open(self, "vbucks_card.png").convert("RGBA")
        vbucks = ImageUtil.RatioResize(self, vbucks, 49, 49)

        price = str(f"{price:,}")
        textWidth, _ = font.getsize(price)
        canvas.text(
            ImageUtil.CenterX(self, ((textWidth + 15) - vbucks.width),
                              card.width, 450),
            price,
            blendColor,
            font=font,
        )

        card.paste(
            vbucks,
            ImageUtil.CenterX(self, (vbucks.width + (textWidth - 290)),
                              card.width, 436),
            vbucks,
        )

        font = ImageUtil.Font(self, 56)
        textWidth, _ = font.getsize(name)
        change = 0
        if textWidth >= 270:
            # Ensure that the item name does not overflow
            font, textWidth, change = ImageUtil.FitTextX(self, name, 56, 260)
        canvas.text(
            ImageUtil.CenterX(self, textWidth, card.width,
                              (380 + (change / 2))),
            name,
            (255, 255, 255),
            font=font,
        )

        return card
Exemplo n.º 4
0
    def GenerateImage(self, date: str, itemShop: dict):
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        try:
            featured = itemShop["featured"]
            daily = itemShop["daily"]

            # Ensure both Featured and Daily have at least 1 item
            if (len(featured) <= 0) or (len(daily) <= 0):
                raise Exception(
                    f"Featured: {len(featured)}, Daily: {len(daily)}")
        except Exception as e:
            Log.Error(
                self,
                f"Failed to parse Item Shop Featured and Daily items, {e}")

            return False

        # Determine the max amount of rows required for the current
        # Item Shop when there are 3 columns for both Featured and Daily.
        # This allows us to determine the image height.
        rows = max(ceil(len(featured) / 3), ceil(len(daily) / 3))
        shopImage = Image.new("RGB", (1920, ((545 * rows) + 340)))

        try:
            background = ImageUtil.Open(self, "background.png")
            background = ImageUtil.RatioResize(self, background,
                                               shopImage.width,
                                               shopImage.height)
            shopImage.paste(
                background,
                ImageUtil.CenterX(self, background.width, shopImage.width))
        except FileNotFoundError:
            Log.Warn(self,
                     "Failed to open background.png, defaulting to dark gray")
            shopImage.paste((18, 18, 18),
                            [0, 0, shopImage.size[0], shopImage.size[1]])

        logo = ImageUtil.Open(self, "logo.png")
        logo = ImageUtil.RatioResize(self, logo, 0, 210)
        shopImage.paste(
            logo, ImageUtil.CenterX(self, logo.width, shopImage.width, 20),
            logo)

        canvas = ImageDraw.Draw(shopImage)
        font = ImageUtil.Font(self, 48)
        textWidth, _ = font.getsize(date)
        canvas.text(
            ImageUtil.CenterX(self, textWidth, shopImage.width, 255),
            date,
            (255, 255, 255),
            font=font,
        )
        canvas.text((20, 255), "Featured", (255, 255, 255), font=font)
        textWidth, _ = font.getsize("Daily")
        canvas.text(
            (shopImage.width - (textWidth + 20), 255),
            "Daily",
            (255, 255, 255),
            font=font,
        )

        # Track grid position
        i = 0

        for item in featured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (20 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1

        # Reset grid position
        i = 0

        for item in daily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (990 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1

        try:
            shopImage.save("itemshop.png")
            Log.Success(self, "Generated Item Shop image")

            return True
        except Exception as e:
            Log.Error(self, f"Failed to save Item Shop image, {e}")
Exemplo n.º 5
0
    def GenerateCard(self, item: dict):
        """Return the card image for the provided Fortnite Item Shop item."""

        try:
            name = item["items"][0]["name"]
            rarity = item["items"][0]["rarity"]
            displayrarity = item["items"][0]["displayRarity"]
            category = item["items"][0]["type"]
            price = str(item["finalPrice"])
            if (category == "outfit") or (category == "wrap"):
                if item["items"][0]["images"]["featured"] is not None:
                    icon = item["items"][0]["images"]["featured"]["url"]
                else:
                    icon = item["items"][0]["images"]["icon"]["url"]
            else:
                icon = item["items"][0]["images"]["icon"]["url"]
        except Exception as e:
            Log.Error(self, f"Failed to parse item {name}, {e}")

            return

        if rarity == "common":
            blendColor = (190, 190, 190)
        elif rarity == "uncommon":
            blendColor = (96, 170, 58)
        elif rarity == "rare":
            blendColor = (73, 172, 242)
        elif rarity == "epic":
            blendColor = (177, 91, 226)
        elif rarity == "legendary":
            blendColor = (211, 120, 65)
        elif rarity == "marvel":
            blendColor = (197, 51, 52)
        elif rarity == "dark":
            blendColor = (251, 34, 223)
        elif rarity == "dc":
            blendColor = (84, 117, 199)
        else:
            blendColor = (255, 255, 255)

        card = Image.new("RGBA", (300, 545))

        try:
            layer = ImageUtil.Open(self, f"card_top_{rarity.lower()}.png")
        except FileNotFoundError:
            Log.Warn(
                self,
                f"Failed to open card_top_{rarity.lower()}.png, defaulted to Common",
            )
            layer = ImageUtil.Open(self, "card_top_common.png")

        card.paste(layer)

        if category == 'glider':
            x = 285 / 1.1
            y = 365 / 1.8
            distanceTop = 60
        elif category == 'music':
            x = 285 / 1.1
            y = 365 / 1.6
            distanceTop = 55
        elif category == 'pickaxe':
            x = 285 / 1.1
            y = 365 / 1.3
            distanceTop = 40
        elif category == 'wrap':
            x = 285 / 1.1
            y = 365 / 1.3
            distanceTop = 40
        else:
            x = 285
            y = 365
            distanceTop = 10

        icon = ImageUtil.Download(self, icon)
        icon = ImageUtil.RatioResize(self, icon, x, y)
        card.paste(
            icon,
            ImageUtil.CenterX(self,
                              icon.width,
                              card.width,
                              distanceTop=distanceTop), icon)

        if len(item["items"]) > 1:
            # Track grid position
            i = 0

            # Start at position 1 in items array
            for extra in item["items"][1:]:
                try:
                    extraRarity = extra["rarity"]
                    extraIcon = extra["images"]["smallIcon"]["url"]
                except Exception as e:
                    Log.Error(self, f"Failed to parse item {name}, {e}")

                    return

                try:
                    layer = ImageUtil.Open(
                        self, f"box_bottom_{extraRarity.lower()}.png")
                except FileNotFoundError:
                    Log.Warn(
                        self,
                        f"Failed to open box_bottom_{extraRarity.lower()}.png, defaulted to Common",
                    )
                    layer = ImageUtil.Open(self, "box_bottom_common.png")

                card.paste(layer, (17, (17 + ((i // 1) * (layer.height)))))

                extraIcon = ImageUtil.Download(self, extraIcon)
                extraIcon = ImageUtil.RatioResize(self, extraIcon, 75, 75)

                card.paste(extraIcon,
                           (17, (17 + ((i // 1) * (extraIcon.height)))),
                           extraIcon)

                try:
                    layer = ImageUtil.Open(
                        self, f"box_faceplate_{extraRarity.lower()}.png")
                except FileNotFoundError:
                    Log.Warn(
                        self,
                        f"Failed to open box_faceplate_{extraRarity.lower()}.png, defaulted to Common",
                    )
                    layer = ImageUtil.Open(self, "box_faceplate_common.png")

                card.paste(layer, (17, (17 + ((i // 1) * (layer.height)))),
                           layer)

                i += 1

        try:
            layer = ImageUtil.Open(self,
                                   f"card_faceplate_{rarity.lower()}.png")
        except FileNotFoundError:
            Log.Warn(
                self,
                f"Failed to open card_faceplate_{rarity.lower()}.png, defaulted to Common",
            )
            layer = ImageUtil.Open(self, "card_faceplate_common.png")

        card.paste(layer, layer)

        try:
            layer = ImageUtil.Open(self, f"card_bottom_{rarity.lower()}.png")
        except FileNotFoundError:
            Log.Warn(
                self,
                f"Failed to open card_bottom_{rarity.lower()}.png, defaulted to Common",
            )
            layer = ImageUtil.Open(self, "card_bottom_common.png")

        card.paste(layer, layer)

        canvas = ImageDraw.Draw(card)

        font = ImageUtil.Font(self, 30)
        textWidth, _ = font.getsize(f"{displayrarity} {category.title()}")
        canvas.text(
            ImageUtil.CenterX(self, textWidth, card.width, 385),
            f"{displayrarity} {category.title()}",
            blendColor,
            font=font,
        )

        vbucks = ImageUtil.Open(self, "vbucks.png")
        vbucks = ImageUtil.RatioResize(self, vbucks, 25, 25)

        textWidth, _ = font.getsize(price)
        canvas.text(
            ImageUtil.CenterX(self, ((textWidth - 5) - vbucks.width),
                              card.width, 495),
            price,
            (255, 255, 255),
            font=font,
        )

        card.paste(
            vbucks,
            ImageUtil.CenterX(self, (vbucks.width + (textWidth + 5)),
                              card.width, 495),
            vbucks,
        )

        font = ImageUtil.Font(self, 56)
        textWidth, _ = font.getsize(name)
        if textWidth >= 270:
            # Ensure that the item name does not overflow
            font, textWidth = ImageUtil.FitTextX(self, name, 56, 265)
        canvas.text(
            ImageUtil.CenterX(self, textWidth, card.width, 425),
            name,
            (255, 255, 255),
            font=font,
        )

        return card
Exemplo n.º 6
0
    def GenerateImage(self, date: str, itemShop: dict):
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        try:
            featured = itemShop["featured"] + itemShop["specialFeatured"]
            daily = itemShop["daily"] + itemShop["specialDaily"]

            if (len(featured) <= 0) or (len(daily) <= 0):
                raise Exception(
                    f"Featured: {len(featured)}, Daily: {len(daily)}")

            if (len(featured) >= 1):
                width = 6
                height = max(ceil(len(featured) / 3), ceil(len(daily) / 3))

                rowsDaily = 3
                rowsFeatured = 3

                dailyStartX = ((340 * 3))

            if (len(featured) >= 18):
                width = 9
                height = max(ceil(len(featured) / 6), ceil(len(daily) / 6))

                rowsDaily = 3
                rowsFeatured = 6

                dailyStartX = ((340 * 6))

            if (len(featured) >= 18) and (len(daily) >= 18):
                width = 12
                height = max(ceil(len(featured) / 6), ceil(len(daily) / 6))

                rowsDaily = 6
                rowsFeatured = 6

                dailyStartX = ((340 * 6) + 100)

        except Exception as e:
            log.critical(f"Failed to parse Item Shop Featured and Daily items, {e}")
            return False

        # Determine the max amount of rows required for the current
        # Item Shop when there are 3 columns for both Featured and Daily.
        # This allows us to determine the image height.

        shopImage = Image.new("RGB", (((340 * width) - 30), (530 * height) + 350))

        try:
            background = ImageUtil.Open(self, "background.png")
            background = ImageUtil.RatioResize(
                self, background, shopImage.width, shopImage.height
            )
            shopImage.paste(
                background, ImageUtil.CenterX(
                    self, background.width, shopImage.width)
            )
        except FileNotFoundError:
            log.warning(
                "Failed to open background.png, defaulting to dark gray")
            shopImage.paste(
                (34, 37, 40), [0, 0, shopImage.size[0], shopImage.size[1]])

        canvas = ImageDraw.Draw(shopImage)
        font = ImageUtil.Font(self, 80)

        textWidth, _ = font.getsize("FORTNITE ITEM SHOP")
        canvas.text(ImageUtil.CenterX(self, textWidth, shopImage.width, 30), "FORTNITE ITEM SHOP", (255, 255, 255), font=font)
        textWidth, _ = font.getsize(date.upper())
        canvas.text(ImageUtil.CenterX(self, textWidth, shopImage.width, 120), date.upper(), (255, 255, 255), font=font)
        
        canvas.text((20, 240), "FEATURED", (255, 255, 255), font=font, anchor=None, spacing=4, align="left")
        canvas.text((shopImage.width - 230, 240), "DAILY", (255, 255, 255), font=font, anchor=None, spacing=4, align="right")

        # Track grid position
        i = 0

        for item in featured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (20 + ((i % rowsFeatured) * (310 + 20))),
                        (350 + ((i // rowsFeatured) * (510 + 20))),
                    ),
                    card,
                )

                i += 1

        # Reset grid position
        i = 0

        for item in daily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (dailyStartX + ((i % rowsDaily) * (310 + 20))),
                        (350 + ((i // rowsDaily) * (510 + 20))),
                    ),
                    card,
                )

                i += 1

        try:
            shopImage.save("itemshop.jpeg", optimize=True,quality=85)
            if(itemShop["fullShop"] == False):
             log.info("Some cosmetics are missing from this shop!")
            log.info("Generated Item Shop image")

            return True
        except Exception as e:
            log.critical(f"Failed to save Item Shop image, {e}")
Exemplo n.º 7
0
    def GenerateCard(self, item: dict):
        """Return the card image for the provided Fortnite Item Shop item."""

        try:
            name = item["name"].lower()
            rarity = item["rarity"].lower()
            category = item["type"].lower()
            price = item["price"]


            if (item["image"]):
                icon = item["image"]
            else:
                icon = item["icon"]

        except Exception as e:
            log.error(f"Failed to parse item {name}, {e}")

            return

        if rarity == "frozen series":
            blendColor = (148, 223, 255)
            rarity = "Frozen"
        elif rarity == "lava series":
            blendColor = (234, 141, 35)
            rarity = "Lava"
        elif rarity == "legendary":
            blendColor = (211, 120, 65)
            rarity = "Legendary"
        elif rarity == "slurp series":
            blendColor = (0, 233, 176)
            rarity = "Slurp"
        elif rarity == "dark":
            blendColor = (251, 34, 223)
            rarity = "Dark"
        elif rarity == "star wars series":
            blendColor = (231, 196, 19)
            rarity = "Star Wars"
        elif rarity == "marvel":
            blendColor = (197, 51, 52)
            rarity = "Marvel"
        elif rarity == "dc":
            blendColor = (84, 117, 199)
            rarity = "DC"
        elif rarity == "icon series":
            blendColor = (54, 183, 183)
            rarity = "Icon"
        elif rarity == "shadow series":
            blendColor = (113, 113, 113)
            rarity = "Shadow"
        elif rarity == "platform series":
            blendColor = (117,129,209)
            rarity = "GamingLegends"
        elif rarity == "epic":
            blendColor = (177, 91, 226)
            rarity = "Epic"
        elif rarity == "rare":
            blendColor = (73, 172, 242)
            rarity = "Rare"
        elif rarity == "uncommon":
            blendColor = (96, 170, 58)
            rarity = "Uncommon"
        elif rarity == "common":
            blendColor = (190, 190, 190)
            rarity = "Common"
        else:
            blendColor = (255, 255, 255)
            rarity = "Unknown"

        card = Image.new("RGBA", (310, 510))

        try:
            layer = ImageUtil.Open(
                self, f"./shopTemplates/{rarity.capitalize()}BG.png")
        except FileNotFoundError:
            log.warn(
                f"Failed to open {rarity.capitalize()}BG.png, defaulted to Common")
            layer = ImageUtil.Open(self, "./shopTemplates/CommonBG.png")
        card.paste(layer)

        icon = ImageUtil.Download(self, icon)
        if (category == "outfit") or (category == "emote"):
            icon = ImageUtil.RatioResize(self, icon, 285, 365)
        elif category == "wrap":
            icon = ImageUtil.RatioResize(self, icon, 230, 310)
        else:
            icon = ImageUtil.RatioResize(self, icon, 310, 390)
        if (category == "outfit") or (category == "emote"):
            card.paste(icon, ImageUtil.CenterX(self, icon.width, card.width), icon)
        else:
            card.paste(icon, ImageUtil.CenterX(self, icon.width, card.width, 15), icon)

        try:
            layer = ImageUtil.Open(
                self, f"./shopTemplates/{rarity.capitalize()}OV.png")
        except FileNotFoundError:
            log.warn(
                f"Failed to open {rarity.capitalize()}OV.png, defaulted to Common")
            layer = ImageUtil.Open(self, "./shopTemplates/CommonOV.png")

        card.paste(layer, layer)

        canvas = ImageDraw.Draw(card)

        vbucks = ImageUtil.Open(self, "vbucks.png")
        vbucks = ImageUtil.RatioResize(self, vbucks, 40, 40)

        font = ImageUtil.Font(self, 40)
        price = str(f"{price:,}")
        textWidth, _ = font.getsize(price)

        canvas.text(ImageUtil.CenterX(self, ((textWidth - 5) - vbucks.width), card.width, 347), price, (255, 255, 255), font=font)
        card.paste(vbucks,ImageUtil.CenterX(self, (vbucks.width + (textWidth + 5)), card.width, 350),vbucks)

        font = ImageUtil.Font(self, 40)
        itemName = name.upper().replace(" OUTFIT", "").replace(" PICKAXE", "").replace(" BUNDLE", "")

        if(category == "bundle"):
            itemName = name.upper().replace(" BUNDLE", "")

        textWidth, _ = font.getsize(itemName)

        change = 0
        if textWidth >= 280:
            # Ensure that the item name does not overflow
            font, textWidth, change = ImageUtil.FitTextX(self, itemName, 40, 260)
        canvas.text(ImageUtil.CenterX(self, textWidth, card.width, (400 + (change / 2))), itemName, (255, 255, 255), font=font)
      
        font = ImageUtil.Font(self, 40)
        textWidth, _ = font.getsize(f"{category.upper()}")
        
        change = 0
        if textWidth >= 280:
            # Ensure that the item rarity/type does not overflow
            font, textWidth, change = ImageUtil.FitTextX(self, f"{category.upper()}", 30, 260)
        canvas.text(ImageUtil.CenterX(self, textWidth, card.width, (450 + (change / 2))), f"{category.upper()}", blendColor, font=font)
        return card
Exemplo n.º 8
0
    def GenerateImage(self, date: str, itemShop: dict):
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        if itemShop["featured"] != None:
            featured = itemShop["featured"]["entries"]
        else:
            featured = []

        if itemShop["daily"] != None:
            daily = itemShop["daily"]["entries"]
        else:
            daily = []

        if itemShop["specialFeatured"] != None:
            specialFeatured = itemShop["specialFeatured"]["entries"]
        else:
            specialFeatured = []

        if itemShop["specialDaily"] != None:
            specialDaily = itemShop["specialDaily"]["entries"]
        else:
            specialDaily = []

        # Determine the max amount of rows required for the current
        # Item Shop when there are 3 columns for both Featured and Daily.
        # This allows us to determine the image height.

        rows = max(ceil((len(featured) + len(specialFeatured)) / 3),
                   ceil((len(daily) + len(specialDaily)) / 3))

        shopImage = Image.new("RGB", (1920, ((545 * rows) + 340)))

        try:
            background = ImageUtil.Open(self, "background.png")
            background = ImageUtil.RatioResize(self, background,
                                               shopImage.width,
                                               shopImage.height)
            shopImage.paste(
                background,
                ImageUtil.CenterX(self, background.width, shopImage.width))
        except FileNotFoundError:
            log.warn("Failed to open background.png, defaulting to dark gray")
            shopImage.paste((18, 18, 18),
                            [0, 0, shopImage.size[0], shopImage.size[1]])

        logo = ImageUtil.Open(self, "logo.png")
        logo = ImageUtil.RatioResize(self, logo, 0, 210)
        shopImage.paste(
            logo, ImageUtil.CenterX(self, logo.width, shopImage.width, 20),
            logo)

        canvas = ImageDraw.Draw(shopImage)
        font = ImageUtil.Font(self, 48)
        textWidth, _ = font.getsize(date)
        canvas.text(
            ImageUtil.CenterX(self, textWidth, shopImage.width, 255),
            date,
            (255, 255, 255),
            font=font,
        )
        featureds = itemShop["featured"]["name"]
        dailys = itemShop["daily"]["name"]

        canvas.text((20, 255), f"{featureds}", (255, 255, 255), font=font)
        textWidth, _ = font.getsize(f"{dailys}")
        canvas.text(
            (shopImage.width - (textWidth + 20), 255),
            f"{dailys}",
            (255, 255, 255),
            font=font,
        )

        # Track grid position
        i = 0

        for item in specialFeatured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (20 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1

        for item in featured:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (20 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1

        # Reset grid position
        i = 0

        for item in specialDaily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (990 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1

        for item in daily:
            card = Athena.GenerateCard(self, item)

            if card is not None:
                shopImage.paste(
                    card,
                    (
                        (990 + ((i % 3) * (card.width + 5))),
                        (315 + ((i // 3) * (card.height + 5))),
                    ),
                    card,
                )

                i += 1
        try:
            shopImage.save("itemshop.png")
            log.info("Generated Item Shop image")

            return True
        except Exception as e:
            log.critical(f"Failed to save Item Shop image, {e}")