Beispiel #1
0
    def getMatrix(self):
        #grab a screen cap and apply some filters to make it easier to work with
        cap = ImageGrab.grab(self.GAME_BOX)
        cap = cap.filter(ImageFilter.MinFilter)
        cap = cap.filter(ImageFilter.MaxFilter)
        cap = posterize(cap, 3)

        #first pass
        #look for color values in the expected gem locations
        #group identical color values together - same gem type
        colors = dict()
        for col in range(self.COLS):
            for row in range(self.ROWS):
                cx = (row * self.CELLW) + self.CELLW / 2
                cy = (col * self.CELLH) + self.CELLH / 2
                sample_rect = (cx - 3, cy + 14, cx + 3, cy + 21)
                sample_rect = map(int, sample_rect)
                sample = cap.crop(sample_rect)
                color = sorted(sample.getcolors(
                    (2 * self.SAMPLE_SIZE)**2))[-1][1]
                self.matrix[col][row] = color
                if color in colors:
                    colors[color] += 1
                else:
                    colors[color] = 1

        #break if we found too little or too many colors on first pass
        numColors = len(colors)
        if numColors < self.NUM_GEMS or numColors > len(ascii_uppercase):
            return None

        #almost always going to be more gems type than there should be
        #merge closest pixel value groups until the expected amount of gems is reached
        #keep track of the ones we merged, probably flashing gems so worth extra points
        color_map = dict(zip(colors, ascii_uppercase))
        for i in range(len(colors) - self.NUM_GEMS):
            rarest = min(colors, key=colors.get)
            minDist, merge = float("inf"), None
            for color in colors:
                if not color == rarest:
                    #use geometric distance between RGB values (my own idea)
                    dist = sum([(a - b)**2 for a, b in zip(color, rarest)])
                    if dist < minDist:
                        minDist = dist
                        merge = color

            colors[merge] += 1
            colors[rarest] = colors[merge]
            color_map[rarest] = color_map[merge]

        #make matrix easier to read by replacing values with letters
        #mostly for debugging
        for row in self.matrix:
            for index, color in enumerate(row):
                row[index] = color_map[color]

        return self.matrix
Beispiel #2
0
 def getMatrix(self):
     #grab a screen cap and apply some filters to make it easier to work with
     cap = ImageGrab.grab(self.GAME_BOX)
     cap = cap.filter(ImageFilter.MinFilter)
     cap = cap.filter(ImageFilter.MaxFilter)
     cap = posterize(cap, 3)
     
     #first pass
     #look for color values in the expected gem locations
     #group identical color values together - same gem type
     colors = dict()
     for col in range(self.COLS):
         for row in range(self.ROWS):
             cx = (row * self.CELLW) + self.CELLW / 2
             cy = (col * self.CELLH) + self.CELLH / 2     
             sample_rect = (cx - 3, cy + 14,
                            cx + 3, cy + 21)
             sample_rect = map(int, sample_rect)
             sample = cap.crop(sample_rect)
             color = sorted(sample.getcolors((2 * self.SAMPLE_SIZE) ** 2))[-1][1]
             self.matrix[col][row] = color
             if color in colors:
                 colors[color] += 1
             else:
                 colors[color] = 1
 
     #break if we found too little or too many colors on first pass
     numColors = len(colors)
     if numColors < self.NUM_GEMS or numColors > len(ascii_uppercase):
         return None
     
     #almost always going to be more gems type than there should be
     #merge closest pixel value groups until the expected amount of gems is reached
     #keep track of the ones we merged, probably flashing gems so worth extra points
     color_map = dict(zip(colors, ascii_uppercase))
     for i in range(len(colors) - self.NUM_GEMS): 
         rarest = min(colors, key=colors.get)
         minDist, merge = float("inf"), None
         for color in colors:
             if not color == rarest:
                 #use geometric distance between RGB values (my own idea)
                 dist = sum([(a - b) ** 2 for a, b in zip(color, rarest)])
                 if dist < minDist:
                     minDist = dist
                     merge = color
         
         colors[merge] += 1
         colors[rarest] = colors[merge]
         color_map[rarest] = color_map[merge]
     
     #make matrix easier to read by replacing values with letters
     #mostly for debugging
     for row in self.matrix:
         for index, color in enumerate(row):
             row[index] = color_map[color]
                 
     return self.matrix
Beispiel #3
0
def _transform(image, difficulty):
    transformations = ['transpose']
    if difficulty in ('normal', 'hard'):
        transformations.append('blur')
    if difficulty == 'hard':
        transformations.append('color')
    transformation = choice(transformations)
    if transformation == 'transpose':
        direction = choice((
            Image.FLIP_LEFT_RIGHT, Image.FLIP_TOP_BOTTOM, Image.TRANSPOSE,
            Image.ROTATE_90, Image.ROTATE_180, Image.ROTATE_270))
        return image.transpose(direction)
    elif transformation == 'blur':
        return image.filter(GaussianBlur(8))
    else:  # transformation == color
        color_trf_method = choice((
            grayscale, invert, lambda img: posterize(img, 4)))
        return color_trf_method(image)
    async def avatareasterify(self, ctx: commands.Context,
                              *colours: Union[discord.Colour, str]) -> None:
        """
        This "Easterifies" the user's avatar.

        Given colours will produce a personalised egg in the corner, similar to the egg_decorate command.
        If colours are not given, a nice little chocolate bunny will sit in the corner.
        Colours are split by spaces, unless you wrap the colour name in double quotes.
        Discord colour names, HTML colour names, XKCD colour names and hex values are accepted.
        """
        async def send(*args, **kwargs) -> str:
            """
            This replaces the original ctx.send.

            When invoking the egg decorating command, the egg itself doesn't print to to the channel.
            Returns the message content so that if any errors occur, the error message can be output.
            """
            if args:
                return args[0]

        async with ctx.typing():

            # Grabs image of avatar
            image_bytes = await ctx.author.avatar_url_as(size=256).read()

            old = Image.open(BytesIO(image_bytes))
            old = old.convert("RGBA")

            # Grabs alpha channel since posterize can't be used with an RGBA image.
            alpha = old.getchannel("A").getdata()
            old = old.convert("RGB")
            old = posterize(old, 6)

            data = old.getdata()
            setted_data = set(data)
            new_d = {}

            for x in setted_data:
                new_d[x] = self.closest(x)
                await asyncio.sleep(
                    0)  # Ensures discord doesn't break in the background.
            new_data = [(*new_d[x], alpha[i]) if x in new_d else x
                        for i, x in enumerate(data)]

            im = Image.new("RGBA", old.size)
            im.putdata(new_data)

            if colours:
                send_message = ctx.send
                ctx.send = send  # Assigns ctx.send to a fake send
                egg = await ctx.invoke(self.bot.get_command("eggdecorate"),
                                       *colours)
                if isinstance(
                        egg,
                        str):  # When an error message occurs in eggdecorate.
                    return await send_message(egg)

                ratio = 64 / egg.height
                egg = egg.resize(
                    (round(egg.width * ratio), round(egg.height * ratio)))
                egg = egg.convert("RGBA")
                im.alpha_composite(
                    egg, (im.width - egg.width,
                          (im.height - egg.height) // 2))  # Right centre.
                ctx.send = send_message  # Reassigns ctx.send
            else:
                bunny = Image.open(
                    Path("bot/resources/easter/chocolate_bunny.png"))
                im.alpha_composite(
                    bunny, (im.width - bunny.width,
                            (im.height - bunny.height) // 2))  # Right centre.

            bufferedio = BytesIO()
            im.save(bufferedio, format="PNG")

            bufferedio.seek(0)

            file = discord.File(bufferedio, filename="easterified_avatar.png"
                                )  # Creates file to be used in embed
            embed = discord.Embed(
                name="Your Lovely Easterified Avatar",
                description=
                "Here is your lovely avatar, all bright and colourful\nwith Easter pastel colours. Enjoy :D"
            )
            embed.set_image(url="attachment://easterified_avatar.png")
            embed.set_footer(text=f"Made by {ctx.author.display_name}",
                             icon_url=ctx.author.avatar_url)

        await ctx.send(file=file, embed=embed)
Beispiel #5
0
def convertp(my_file):
    new_file = my_file + "_p"
    img = Image.open(my_file)
    img = posterize(img, 2)
    img.save(new_file, "PNG")
    os.remove(my_file)