示例#1
0
 def get_image(url, file_dir):
     try:
         data = urllib2.urlopen(url, timeout=gk7.HTTP_TIME_OUT).read()
         # 文件路径
         file_path = '%s/%s' % (file_dir, url[url.rfind('/') + 1:])
         with open(file_path, 'w') as f_data:
             f_data.write(data)
         # 压缩
         ImageUtil.compress(file_path, gk7.PIC_MAX_WIDTH)
     except Exception as e:
         ## 延迟20s后重试
         DownloadTask.get_image.retry(countdown=20, exc=e)
     return file_path
示例#2
0
 def get_image(url, file_dir):
     try:
         data = urllib2.urlopen(url, timeout=gk7.HTTP_TIME_OUT).read()
         # 文件路径
         file_path = '%s/%s' %(file_dir, url[url.rfind('/')+1:])
         with open(file_path, 'w') as f_data:
             f_data.write(data)
         # 压缩
         ImageUtil.compress(file_path, gk7.PIC_MAX_WIDTH)
     except Exception as e:
         ## 延迟20s后重试
         DownloadTask.get_image.retry(countdown=20, exc=e)
     return file_path
示例#3
0
 def get_image(url, file_dir):
     try:
         data = urllib2.urlopen(url).read()
         # 文件路径
         file_path = '%s/%s' %(file_dir, url[url.rfind('/')+1:])
         with open(file_path, 'w') as f_data:
             f_data.write(data)
         # 压缩
         ImageUtil.compress(file_path, gk7.PIC_MAX_WIDTH)
     except Exception as e:
         logger.error(u'下载文件失败,url:%s,文件目录:%s,原因:%s' %(url, file_dir, str(e)))
         ## 延迟20s后重试
         DownloadTask.get_image.retry(countdown=20, exc=e)
     return file_path
示例#4
0
def GenerateCard5Titles(Language, item):

    card = Image.new("RGBA", (384, 50))

    canvas = ImageDraw.Draw(card)

    if Language == "ja":
        font = ImageFont.truetype('assets/Fonts/NotoSansJP-Bold.otf', 15)
    elif Language == "ko":
        font = ImageFont.truetype('assets/Fonts/NotoSansKR-Regular.otf', 15)
    else:
        font = ImageFont.truetype('assets/Fonts/burbanksmall-black.otf', 15)

    title = item["title"]
    title = title.upper()

    icon = item["image"]
    icon = ImageUtil.Download(item, icon)
    icon = ImageUtil.RatioResize(item, icon, 384, 216)
    card.paste(icon, ImageUtil.CenterX(item, icon.width, card.width))

    ### 1920 * 1080 = 384
    try:
        TINT_COLOR = (0, 0, 205)  # Black
        TRANSPARENCY = 0.7  # Degree of transparency, 0-100%
        OPACITY = int(255 * TRANSPARENCY)

        cardBottom = Image.new("RGBA", (384, 360), TINT_COLOR)
        draw = ImageDraw.Draw(cardBottom)
        draw.rectangle(((384, 360), (0, 0)), fill=TINT_COLOR + (OPACITY, ))
    except Exception as e:
        print(e)
    card.paste(cardBottom, (0, 0), cardBottom)

    textWidth, _ = font.getsize(title)
    if textWidth >= 364:
        # Ensure that the item name does not overflow
        if Language == "ja":
            font, textWidth = ImageUtil.FitTextX2(item, title, 16, 1920)
        elif Language == "ko":
            font, textWidth = ImageUtil.FitTextX1(item, title, 16, 1920)
        else:
            font, textWidth = ImageUtil.FitTextX(item, title, 16, 1920)
    canvas.text(
        ImageUtil.CenterX(item, textWidth, card.width, 15),
        title,
        (255, 255, 255),
        font=font,
    )

    return card
示例#5
0
def downLoadImg(source_url, content_html):
    # 处理图片
    selector = Selector(text=content_html)
    # 解析文档中的所有图片url,然后替换成标识
    image_urls = []
    imgs = selector.xpath(u'descendant::img')

    for img in imgs:
        # 图片可能放在src 或者data-src
        image_url_base = img.xpath(u'@src').extract_first('')
        if not image_url_base:
            continue
        if image_url_base.startswith(u'//'):
            image_url = u'http:' + image_url_base
        elif image_url_base.startswith(u'/'):
            image_url = getNetLoc(source_url) + image_url_base
        elif image_url_base.startswith(u'./'):
            # 得到当前url结尾的最后一个 /之前的字符串
            base_url = source_url[0:source_url.rindex(u'/')] + u'/'
            image_url = image_url_base.replace(u'./', base_url)
        elif image_url_base.startswith(u'../../'):
            image_url = image_url_base.replace(u'../../',
                                               getNetLoc(source_url) + u'/')
        elif image_url_base.startswith(u'http'):
            image_url = image_url_base
        else:
            base_url = source_url[0:source_url.rindex(u'/')] + u'/'
            image_url = base_url + image_url_base
        if image_url and image_url.startswith(u'http'):
            print(u'得到图片:' + image_url)
            image_urls.append({
                u'url': image_url,
            })
            content_html = content_html.replace(image_url_base, image_url)

    # TODO..先不下载
    image_urls = []
    result_image_urls = ImageUtil.downLoadImage(image_urls)
    for item in result_image_urls:
        url = item.get(u'url', u'')
        image_url = item.get(u'image_url', u'')
        content_html = content_html.replace(u'&',
                                            u'&').replace(url, image_url)
    return content_html
示例#6
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
示例#7
0
    def generate_card(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"]

            # Select bundle image and name
            if item["bundle"] is not None:
                name = item["bundle"]["name"]
                icon = item["bundle"]["image"]

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

        # Should be outdated

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

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

        try:
            layer = ImageUtil().open_image(self.style +
                                           f"/card_top_{rarity}.png")
        except FileNotFoundError:
            log.warning(
                f"Failed to open card_top_{rarity}.png, defaulted to Common")
            layer = ImageUtil().open_image(f"{self.style}/card_top_common.png")

        card.paste(layer)

        icon = ImageUtil().download_image(icon).convert("RGBA")
        if category in ["outfit", "emote"]:
            icon = ImageUtil().resize_ratio(icon, 285, 365)
        elif category == "wrap":
            icon = ImageUtil().resize_ratio(icon, 230, 310)
        else:
            icon = ImageUtil().resize_ratio(icon, 310, 390)
        if category in ["outfit", "emote"]:
            card.paste(icon,
                       ImageUtil().align_center(card.width, icon.width), icon)
        else:
            card.paste(icon,
                       ImageUtil().align_center(card.width, icon.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:
                    extra_rarity = extra["rarity"]['value']
                    extra_icon = extra["images"]["smallIcon"]
                except Exception as error:
                    log.error(f"Failed to parse item {name}, {error}")

                    return

                try:
                    layer = ImageUtil().open_image(
                        self.style + f"/box_bottom_{extra_rarity}.png")
                except FileNotFoundError:
                    log.warning(
                        f"Failed to open box_bottom_{extra_rarity}.png, defaulted to Common"
                    )
                    layer = ImageUtil().open_image(
                        f"{self.style}/box_bottom_common.png")

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

                extra_icon = ImageUtil().download_image(extra_icon)
                extra_icon = ImageUtil().resize_ratio(extra_icon, 75, 75)

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

                try:
                    layer = ImageUtil().open_image(
                        self.style + f"/box_faceplate_{extra_rarity}.png")
                except FileNotFoundError:
                    log.warning(
                        f"Failed to open box_faceplate_{extra_rarity}.png, defaulted to Common"
                    )
                    layer = ImageUtil().open_image(
                        f"{self.style}/box_faceplate_common.png")

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

                i += 1

        if self.style == 'old':
            try:
                layer = ImageUtil().open_image(self.style +
                                               f"/card_faceplate_{rarity}.png")
            except FileNotFoundError:
                log.warning(
                    f"Failed to open card_faceplate_{rarity}.png, defaulted to Common"
                )
                layer = ImageUtil().open_image(
                    f"{self.style}/card_faceplate_common.png")

            card.paste(layer, layer)

        try:
            layer = ImageUtil().open_image(self.style +
                                           f"/card_bottom_{rarity}.png")
        except FileNotFoundError:
            log.warning(
                f"Failed to open card_bottom_{rarity}.png, defaulted to Common"
            )
            layer = ImageUtil().open_image(
                f"{self.style}/card_bottom_common.png")

        card.paste(layer, layer)

        canvas = ImageDraw.Draw(card)

        if self.style == 'old':
            font = ImageUtil().get_font(30)
            text_width, _ = font.getsize(
                f"{rarity.capitalize()} {category.capitalize()}")
            canvas.text(
                ImageUtil().align_center(card.width, text_width, 385),
                f"{rarity.capitalize()} {category.capitalize()}",
                blend_color,
                font=font,
            )

            vbucks = ImageUtil().open_image("vbucks.png")
            vbucks = ImageUtil().resize_ratio(vbucks, 25, 25)

            price = str(f"{price:,}")
            text_width, _ = font.getsize(price)
            canvas.text(
                ImageUtil().align_center(card.width,
                                         (text_width - vbucks.width), 495),
                price,
                blend_color,
                font=font,
            )

            card.paste(
                vbucks,
                ImageUtil().align_center(card.width,
                                         (vbucks.width + (text_width + 5)),
                                         495),
                vbucks,
            )

            font = ImageUtil().get_font(56)
            text_width, _ = font.getsize(name)
            change = 0
            if text_width >= 270:
                # Ensure that the item name does not overflow
                font, text_width, change = ImageUtil().fit_text(name, 56, 260)
            canvas.text(
                ImageUtil().align_center(card.width, text_width,
                                         (425 + (change // 2))),
                name,
                (255, 255, 255),
                font=font,
            )
        elif self.style == 'new':
            font = ImageUtil().get_font(33)

            vbucks = ImageUtil().open_image("vbucks_card.png")
            vbucks = ImageUtil().resize_ratio(vbucks, 49, 49)

            price = str(f"{price:,}")
            text_width, _ = font.getsize(price)
            canvas.text(
                ImageUtil().align_center(card.width,
                                         ((text_width + 15) - vbucks.width),
                                         450),
                price,
                blend_color,
                font=font,
            )

            card.paste(
                vbucks,
                ImageUtil().align_center(card.width,
                                         (vbucks.width + (text_width - 290)),
                                         436),
                vbucks,
            )

            font = ImageUtil().get_font(56)
            text_width, _ = font.getsize(name)
            change = 0
            if text_width >= 270:
                # Ensure that the item name does not overflow
                font, text_width, change = ImageUtil().fit_text(name, 56, 260)
            canvas.text(
                ImageUtil().align_center(card.width, text_width,
                                         (380 + (change // 2))),
                name,
                (255, 255, 255),
                font=font,
            )

        return card
示例#8
0
    def generate_image(self, date: str, item_shop: dict) -> bool:
        """
        Generate the Item Shop image using the provided Item Shop.

        Return True if image sucessfully saved.
        """

        if item_shop["featured"] is not None:
            featured = item_shop["featured"]["entries"]
        else:
            featured = []

        if item_shop["daily"] is not None:
            daily = item_shop["daily"]["entries"]
        else:
            daily = []

        # 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))

        shop_image = Image.new("RGBA", (1920, ((545 * rows) + 340)))

        try:
            background = ImageUtil().open_image("background.png")
            background = ImageUtil().resize_ratio(background, shop_image.width,
                                                  shop_image.height)
            shop_image.paste(
                background,
                ImageUtil().align_center(shop_image.width, background.width))
        except FileNotFoundError:
            log.warning(
                "Failed to open background.png, defaulting to dark gray")
            shop_image.paste((18, 18, 18),
                             [0, 0, shop_image.size[0], shop_image.size[1]])

        logo = ImageUtil().open_image("logo.png")
        logo = ImageUtil().resize_ratio(logo, 0, 210)
        shop_image.paste(
            logo,
            ImageUtil().align_center(shop_image.width, logo.width, 20), logo)

        canvas = ImageDraw.Draw(shop_image)

        font = ImageUtil().get_font(48)
        text_width, _ = font.getsize(date)
        canvas.text(
            ImageUtil().align_center(shop_image.width, text_width, 255),
            date,
            (255, 255, 255),
            font=font,
        )
        featured_title = Translator().translate("Featured",
                                                str='en',
                                                dest=self.language).text
        daily_title = Translator().translate("Daily",
                                             str='en',
                                             dest=self.language).text

        canvas.text((20, 255), featured_title, (255, 255, 255), font=font)
        text_width, _ = font.getsize(daily_title)
        canvas.text(
            (shop_image.width - (text_width + 20), 255),
            daily_title,
            (255, 255, 255),
            font=font,
        )

        # Track grid position
        i = 0

        for item in featured:
            card = self.generate_card(item)

            if card is not None:
                shop_image.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 = self.generate_card(item)

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

                i += 1

        try:
            shop_image.save("itemshop.png")
            log.info("Generated Item Shop image")
            return True
        except Exception as error:
            log.critical(f"Failed to save Item Shop image, {error}")
        return False
    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
    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}")
示例#11
0
def generate_panel(
    panel: dict,
    colors: dict,
    session: Optional[requests.Session] = requests.Session()
) -> Image.Image:
    image = Image.new('RGB', get_size(panel))
    canvas = ImageDraw.Draw(image)
    image2 = Image.new('RGBA', (image.width * 2, image.height * 2))
    canvas2 = ImageDraw.Draw(image2)
    size = get_size(panel)
    background = ImageUtil.ratio_resize(
        ImageUtil.get_image(panel['displayAssets'][0]['background'],
                            session).convert('RGBA'), *size)
    image.paste(background, ImageUtil.center_x(background.width, image.width,
                                               0), background)
    display_asset = ImageUtil.ratio_resize(
        ImageUtil.get_image(panel['displayAssets'][0]['url'],
                            session).convert('RGBA'), *size)
    image.paste(display_asset,
                ImageUtil.center_x(display_asset.width, image.width, 0),
                display_asset)

    canvas.polygon(
        ((0, size[1] - PRICE_HEIGHT), (size[0], size[1] - PRICE_HEIGHT),
         (size[0], size[1]), (0, size[1])),
        fill=(14, 14, 14))
    vbucks = ImageUtil.ratio_resize(
        ImageUtil.open('vbucks.png').point(lambda x: x * 0.8).convert(
            'RGBA').rotate(-15), 40, 40)
    pos = size[0] - vbucks.width - 5
    image.paste(vbucks, (pos, size[1] - vbucks.height + 10), vbucks)
    text = f"{panel['price']['finalPrice']:,}"
    fonts = name_fonts.fonts_size(15, 15, 15)
    x, y = fonts.text_size(text)
    pos = pos - x - 3
    fonts.write_text(canvas,
                     text, (pos, size[1] - y - 4),
                     fill=(160, 175, 185))

    if panel['price']['finalPrice'] != panel['price']['regularPrice']:
        text = f"{panel['price']['regularPrice']:,}"
        fonts = name_fonts.fonts_size(15, 15, 15)
        x, y = fonts.text_size(text)
        pos = pos - x - 6
        fonts.write_text(canvas,
                         text, (pos, size[1] - y - 4),
                         fill=(100, 100, 100))
        canvas2.line((((pos - 2) * 2, (size[1] - y - 4 + 10) * 2),
                      ((pos + x + 3) * 2, (size[1] - y - 4 + 6) * 2)),
                     fill=(100, 110, 110),
                     width=3 * 2)

    canvas2.polygon(
        ((0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - RARITY_HEIGHT) * 2),
         (size[0] * 2,
          (size[1] - PRICE_HEIGHT - NAME_HEIGHT - RARITY_HEIGHT - SLOPE) * 2),
         (size[0] * 2, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - SLOPE) * 2),
         (0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT) * 2)),
        fill=colors[panel['series']['id']
                    if panel['series'] is not None else panel['rarity']['id']])
    canvas2.polygon(
        ((0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT) * 2),
         (size[0] * 2, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - SLOPE) * 2),
         (size[0] * 2,
          (size[1] - PRICE_HEIGHT) * 2), (0, (size[1] - PRICE_HEIGHT) * 2)),
        fill=(30, 30, 30))
    image2.thumbnail(image.size, Image.LANCZOS)
    image.paste(image2, (0, 0), image2)

    fonts = name_fonts.fonts_size(20, 20, 20)
    x, y = fonts.text_size(panel['displayName'])
    fonts.write_text(canvas,
                     panel['displayName'],
                     ImageUtil.center_x(x, image.width,
                                        size[1] - PRICE_HEIGHT - y - 10),
                     fill=(255, 255, 255))

    icons = [
        ImageUtil.ratio_resize(
            ImageUtil.open(filename).convert('RGBA'), 30, 30)
        for filename in set(
            itertools.chain(*[
                get_user_facing_flag_images(item) for item in panel['granted']
            ]))
    ]
    x = size[0] - 10
    for icon in icons:
        x -= icon.width
        image.paste(icon, (x, size[1] - PRICE_HEIGHT - NAME_HEIGHT -
                           RARITY_HEIGHT - 15 - icon.height), icon)
        x -= 10

    return image
示例#12
0
def generate_section(
    section: dict,
    colors: dict,
    now: datetime.datetime,
    session: Optional[requests.Session] = requests.Session()
) -> Image.Image:
    if len(section['panels']
           ) == 1 and section['panels'][0]['tileSize'] == 'Small':
        image = Image.new('RGBA', (MARGIN_LEFT + get_section_width(section) +
                                   MARGIN_RIGHT, Y_MARGIN + SMALL_SIZE[1]))
    else:
        image = Image.new('RGBA', (MARGIN_LEFT + get_section_width(section) +
                                   MARGIN_RIGHT, Y_MARGIN + NORMAL_SIZE[1]))
    canvas = ImageDraw.Draw(image)

    x = MARGIN_LEFT
    size = 50
    if section['name']:
        fonts = name_fonts.fonts_size(size, size, size)
        x = 50
        final_x, _ = fonts.write_text(canvas, section['name'].upper(),
                                      (x, Y_MARGIN // 2 - 25))
        x += final_x
    if section['until'] is not None:
        timer = ImageUtil.ratio_resize(
            ImageUtil.open('shop_timer.png').convert('RGBA'), size, size)
        x += 12
        image.paste(timer, (x, Y_MARGIN // 2 - 15 - 4), timer)

        end = section['until'] - now
        m, s = divmod(end.seconds, 60)
        h, m = divmod(m, 60)
        timer_text = ("{}:{:0>2}:{:0>2}".format(h, m, s)
                      if end > datetime.timedelta(hours=1) else
                      "{}:{:0>2}".format(m, s))
        x += timer.width + 6
        fonts = name_fonts.fonts_size(size // 2, size // 2, size // 2)
        _, y = fonts.text_size(timer_text)
        fonts.write_text(canvas,
                         timer_text, (x, Y_MARGIN // 2 - 15 + y // 2),
                         fill=(115, 200, 235))

    with ThreadPoolExecutor() as executor:
        futures = [
            executor.submit(generate_panel, panel, colors, session)
            for panel in section['panels']
        ]

    x = MARGIN_LEFT
    small_count = 0
    for num, future in enumerate(futures):
        try:
            panel_image = future.result()
        except Exception:
            print('Failed to generate panel', file=sys.stderr)
            traceback.print_exc()
        else:
            panel = section['panels'][num]
            size = get_size(panel)
            if panel['tileSize'] == 'Small':
                small_count += 1
                if small_count % 2 == 1:
                    pos = (x, Y_MARGIN)
                    x += size[0] + X_MARGIN
                else:
                    pos = (x - size[0] - X_MARGIN,
                           Y_MARGIN + (NORMAL_SIZE[1] - size[1] * 2) + size[1])
            else:
                pos = (x, Y_MARGIN)
                x += size[0] + X_MARGIN
            image.paste(panel_image, pos)
            if panel['banner'] is not None:
                font_size, minus = name_fonts.fit_fonts_size(
                    image.width - 25, 16, panel['banner']['name'])
                fonts = name_fonts.fonts_size(font_size, font_size, font_size)
                text_width = fonts.text_size(panel['banner']['name'])[0]
                banner_height = 32
                color = 'red' if panel['banner'][
                    'intensity'] == 'Low' else 'yellow'
                banner_rear = ImageUtil.ratio_resize(
                    ImageUtil.open(f'{color}_banner_rear.png').convert('RGBA'),
                    0,
                    banner_height,
                    resample=Image.BICUBIC)
                banner_middle = ImageUtil.open(
                    f'{color}_banner_middle.png').convert('RGBA').resize(
                        (text_width, banner_height))
                banner_front = ImageUtil.ratio_resize(ImageUtil.open(
                    f'{color}_banner_front.png').convert('RGBA'),
                                                      0,
                                                      banner_height,
                                                      resample=Image.BICUBIC)
                image.paste(banner_rear, (pos[0] - 15, pos[1] - 15),
                            banner_rear)
                image.paste(banner_middle,
                            (pos[0] - 15 + banner_rear.width, pos[1] - 15),
                            banner_middle)
                image.paste(banner_front, (pos[0] - 15 + banner_rear.width +
                                           banner_middle.width, pos[1] - 15),
                            banner_front)
                fonts.write_text(
                    canvas,
                    panel['banner']['name'],
                    (pos[0] - 15 + banner_rear.width, pos[1] - 15 + 5),
                    fill=(255, 255,
                          255) if panel['banner']['intensity'] == 'Low' else
                    (0, 0, 0))

    return image
示例#13
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}")
示例#14
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}")
示例#15
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}")
示例#16
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}")
示例#17
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
示例#18
0
    def GenerateCard(self, card: dict, namefont: str,
                     categoryfont: str) -> ("PIL Image", None):
        Card = Image.new("RGB", (300, 545))

        name = card["items"][0]["name"]
        category = card["items"][0]["type"]
        displaycategory = card["items"][0]["displayType"]
        rarity = card["items"][0]["rarity"]
        backend_rarity = card["items"][0]["backendRarity"].replace(
            "EFortRarity::", "", 1).lower()
        regularprice = card["regularPrice"]
        finalprice = card["finalPrice"]
        regularprice = str(f"{regularprice:,}")
        finalprice = str(f"{finalprice:,}")
        banner = card["banner"]

        if category == "outfit" or category == "wrap" or category == "banner":
            if card["items"][0]["images"]["featured"] is not None:
                icon = card["items"][0]["images"]["featured"]["url"]
            else:
                log.debug("featured image not found, changing to icon")
                icon = card["items"][0]["images"]["icon"]["url"]
        else:
            icon = card["items"][0]["images"]["icon"]["url"]

        icon = ImageUtil.GET_Image(self, icon).convert("RGBA")
        if category == "backpack" or category == "pickaxe" or category == "glider" or category == "wrap" or category == "music":
            icon = ImageUtil.RatioResize(self, icon, Card.width // 1.6,
                                         Card.height // 1.6)
        else:
            icon = ImageUtil.RatioResize(self, icon, Card.width, Card.height)
        try:
            try:
                image = ImageUtil.Open(
                    self, f"color_{rarity}.png").convert("RGBA").resize(
                        (Card.width, Card.height)).convert("RGBA")
            except FileNotFoundError as e:
                log.warning(
                    f"Rarity {rarity} not found, defaulted to backend {backend_rarity}"
                )
                image = ImageUtil.Open(
                    self,
                    f"color_{backend_rarity}.png").convert("RGBA").resize(
                        (Card.width, Card.height)).convert("RGBA")
            Card.paste(image, (0, 0), image)
            if category == "backpack" or category == "pickaxe" or category == "glider" or category == "wrap" or category == "music":
                Card.paste(
                    icon,
                    ImageUtil.CenterX(self, icon.width, Card.width,
                                      icon.width // 6), icon)
            else:
                Card.paste(icon, ImageUtil.CenterX(self, icon.width,
                                                   Card.width), icon)
            image = ImageUtil.Open(self,
                                   f"card_plate_{rarity}.png").convert("RGBA")
            Card.paste(image, (0, 0), image)
            image = ImageUtil.Open(self,
                                   f"card_mask_{rarity}.png").convert("RGBA")
            Card.paste(image, (0, 0), image)

            canvas = ImageDraw.Draw(Card)
            font = ImageUtil.OpenFont(
                self, ImageUtil.FontSize(self, Card.width, 28, name), namefont)
            textwidth, _ = font.getsize(f"{name}")
            canvas.text(ImageUtil.CenterX(self, textwidth, Card.width, 430),
                        f"{name}",
                        font=font)
            font = ImageUtil.OpenFont(
                self, ImageUtil.FontSize(self, Card.width, 20, category),
                categoryfont)
            textwidth, _ = font.getsize(f"{displaycategory}")
            canvas.text(ImageUtil.CenterX(self, textwidth, Card.width, 458),
                        f"{displaycategory}", (160, 160, 160),
                        font=font)

            vbucks = ImageUtil.Open(self, "vbucks.png")
            vbucks = ImageUtil.RatioResize(self, vbucks, 35, 35)
            if regularprice == finalprice:
                regularfont = ImageUtil.OpenFont(self, 28, categoryfont)
                textWidth, _ = font.getsize(regularprice)
                canvas.text(ImageUtil.CenterX(self,
                                              ((textWidth - 5) - vbucks.width),
                                              Card.width, 494),
                            regularprice,
                            font=regularfont)

                Card.paste(
                    vbucks,
                    ImageUtil.CenterX(self, (vbucks.width + (textWidth + 5)),
                                      Card.width, 499), vbucks)
            else:
                finalfont = ImageUtil.OpenFont(self, 28, categoryfont)
                regularfont = ImageUtil.OpenFont(self, 22, categoryfont)
                regularWidth, regularHeight = regularfont.getsize(regularprice)
                Width, Height = regularfont.getsize(
                    regularprice.replace(",", " "))
                finalWidth, finalHeight = finalfont.getsize(finalprice)
                discount = ImageUtil.Open(self, "discount.png")
                discount = discount.resize((Width, Height - 5))
                canvas.text(ImageUtil.CenterX(
                    self, ((finalWidth + regularWidth - 5) - vbucks.width),
                    Card.width, 494),
                            finalprice,
                            font=finalfont)
                Card.paste(
                    vbucks,
                    ImageUtil.CenterX(self, (vbucks.width +
                                             (finalWidth + regularWidth + 5)),
                                      Card.width, 499), vbucks)

                pos = ImageUtil.CenterX(self, (finalWidth + regularWidth - 5) -
                                        vbucks.width, Card.width, 499)
                canvas.text((pos[0] + 60, pos[1]),
                            regularprice, (160, 160, 160),
                            font=regularfont)
                pos2 = ImageUtil.CenterX(
                    self, (finalWidth + regularWidth - 5) - vbucks.width,
                    Card.width, 497 + (discount.height // 2))
                Card.paste(discount, (pos2[0] + 60, pos2[1]), discount)

            if banner is not None:
                font = ImageUtil.OpenFont(self, 20, namefont)
                bannerWidth, bannerHeight = font.getsize(banner)
                banner_middle = ImageUtil.Open(
                    self, "banner_middle.png").convert("RGBA")
                banner_middle = banner_middle.resize((bannerWidth + 45, 35))
                banner_rear = ImageUtil.Open(self,
                                             "banner_rear.png").convert("RGBA")
                banner_rear = ImageUtil.RatioResize_NoAA(
                    self, banner_rear, 0, 35)
                banner_front = ImageUtil.Open(
                    self, "banner_front.png").convert("RGBA")
                banner_front = banner_front.resize((bannerWidth + 45, 35))
                Card.paste(banner_middle, (0, 0), banner_middle)
                Card.paste(banner_rear, (0, 0), banner_rear)
                Card.paste(banner_front, (0, 0), banner_front)
                canvas.text((8, 8), banner, font=font)

            return Card
        except Exception as e:
            log.error(self, f"Failed to generate card, {e}")
            return None
示例#19
0
    def GenerateImage(self,
                      data: dict,
                      date: str,
                      text_override: dict = {},
                      specialoffer: str = "Special Offers",
                      namefont: str = "",
                      categoryfont: str = "") -> bool:
        try:
            Splited = Utility.Split_Special(self, data=data)
            Sorted = Utility.Sort_Item(self, data=Splited)
            Overrided = Utility.Text_Override(
                self, data=Sorted, text_override=text_override['categories'])
            Extracted = Utility.Extract_ItemShop(self, Overrided)
            if len(Extracted['featured']) > 1 or len(
                    Extracted['daily']) > 1 or len(Extracted['special']) > 1:
                if len(Extracted['special']) > 1:
                    rows = max(ceil(len(Extracted['featured']) / 4),
                               ceil(len(Extracted['daily']) / 4),
                               ceil(len(Extracted['special']) / 4))
                    ShopImage = Image.new("RGBA", (3800, ((545 * rows) + 365)))
                else:
                    rows = max(ceil(len(Extracted['featured']) / 4),
                               ceil(len(Extracted['daily']) / 4))
                    ShopImage = Image.new("RGBA", (2550, ((545 * rows) + 365)))

                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")

                for num, unity in enumerate(Extracted.items()):
                    if len(unity[1]) > 1:
                        Unity = ShopBot.GenerateUnity(self, unity[1], namefont,
                                                      categoryfont)
                        if Unity is not None:
                            canvas = ImageDraw.Draw(ShopImage)
                            font = ImageUtil.OpenFont(self, 48, namefont)
                            ShopImage.paste(Unity, ((num * 1200) +
                                                    ((num + 1) * 50), 315),
                                            Unity)
                            if unity[0] != "special":
                                canvas.text(
                                    (50 + (num * 1250), 260),
                                    text_override.get(unity[0],
                                                      unity[0].capitalize()),
                                    font=font)
                            else:
                                canvas.text((50 + (num * 1250), 260),
                                            specialoffer,
                                            font=font)
                    else:
                        log.debug(f"{unity[0]} is None")
            else:
                ShopImage = Image.new("RGBA", (2550, 365))
                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")

                canvas = ImageDraw.Draw(ShopImage)
                font = ImageUtil.OpenFont(self, 48, namefont)
                canvas.text((50, 260),
                            text_override.get("featured", "Featured"),
                            font=font)
                canvas.text((1300, 260),
                            text_override.get("daily", "Daily"),
                            font=font)
                log.info("Shop is None")

            try:
                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),
                    logo)
            except FileNotFoundError:
                log.warning("Failed to open logo.png")

            font = ImageUtil.OpenFont(self, 40, namefont)
            canvas.text((5, 5), date, font=font)

            ShopImage.save("itemshop.png")
            return True
        except Exception as e:
            log.error(self, f"Failed to generate image, {e}")
            return False