Beispiel #1
0
    async def pixelate(self, im: Image.Image):
        root = tk.AsyncToplevel(self._master)
        root.title(self._master.cur_locale.general.corruptions.pixelate)
        root.bar = Progressbar(root,
                               orient="horizontal",
                               length=400,
                               mode="indeterminate")
        root.bar.pack()
        asyncio.get_event_loop().create_task(start(root.bar))
        width, height = im.size
        wdigits = max(-1 * len(str(width)) + 2, 1)
        hdigits = max(-1 * len(str(height)) + 2, 1)
        await asyncio.sleep(0.01)

        factor = hdigits if hdigits > wdigits else wdigits

        width = int(round(width / 2, factor) * 2)
        height = int(round(height / 2, factor) * 2)

        await asyncio.sleep(0.01)
        im = im.resize((width, height))
        await asyncio.sleep(0.01)

        divider = max(10**(-1 * factor) // 5, 1)
        small_width = width // divider
        small_height = height // divider
        await asyncio.sleep(0.01)

        new_im = im.resize((small_width, small_height))
        new_im = new_im.resize((width, height))
        try:
            await root.destroy()
        except Exception:
            pass
        return new_im
Beispiel #2
0
    async def alterpixel2(self, im: Image.Image):
        width, height = im.size

        wdigits = -1 * len(str(width)) + 2
        hdigits = -1 * len(str(height)) + 2

        factor = hdigits if hdigits > wdigits else wdigits

        width = int(round(width / 2, factor) * 2)
        height = int(round(height / 2, factor) * 2)

        im = im.resize((width, height))

        BLOCKLEN = int("2" + "0" * (-1 * factor))

        xblock = width // BLOCKLEN
        yblock = height // BLOCKLEN
        max = xblock * yblock * 2
        root = tk.AsyncToplevel(self._master)
        root.title(self._master.cur_locale.general.corruptions.alterpixel)
        root.bar = Progressbar(root,
                               orient="horizontal",
                               length=400,
                               mode="determinate",
                               maximum=max)
        root.bar.pack()
        blockmap = []
        for yb in range(yblock):
            for xb in range(xblock):
                blockmap.append((
                    xb * BLOCKLEN,
                    yb * BLOCKLEN,
                    (xb + 1) * BLOCKLEN,
                    (yb + 1) * BLOCKLEN,
                ))
                root.bar["value"] += 1
                await asyncio.sleep(0.001)

        shuffle = list(blockmap)
        random.shuffle(shuffle)

        result = Image.new(im.mode, (width, height))
        for box, sbox in zip(blockmap, shuffle):
            c = im.crop(sbox)
            result.paste(c, box)
            root.bar["value"] += 1
            await asyncio.sleep(0.001)
        try:
            await root.destroy()
        except Exception:
            pass
        return result
Beispiel #3
0
    async def save(self, file: typing.Union[str, pathlib.Path]):
        """Shortcut to save the PIL file"""
        # Get the file extension
        ext = str(file).split(".")[-1]
        buffer = BytesIO()

        # Save into buffer
        self.pil_image.save(buffer, format=ext)

        # Find out how many bytes the file holds, and reset file pointer
        max_bytes = buffer.tell()
        buffer.seek(0)

        async with aiofiles.open(file, "wb") as fp:
            # For every byte
            for i in range(max_bytes):
                current_byte = buffer.read(1)
                # Open a window
                root = tk.AsyncToplevel(self._master)
                # ... that the user cannot kill
                root.protocol('WM_DELETE_WINDOW', lambda *i: None)

                async def cb(i=i):  # No late binding
                    # Write the byte
                    await fp.write(current_byte)
                    # ... then kill the root
                    await root.destroy()

                # ... and place a button
                if isinstance(self.master, tk.AsyncFrame):
                    master = self.master.master
                else:
                    master = self.master
                tk.AsyncButton(
                    root,  # ... on the window
                    # ... that says the current byte
                    text=(f"{master.cur_locale.menu.fileselect.write} "
                          f"{current_byte.hex().upper()}"),
                    # ... and writes it on click
                    callback=cb,
                ).pack()
                # ... and wait until the button is pressed (so the user cannot mess up)
                await self._master.wait_window(root)
Beispiel #4
0
 async def alterpixel(self, im: Image.Image):
     root = tk.AsyncToplevel(self._master)
     root.title(self._master.cur_locale.general.corruptions.alterpixel)
     root.bar = Progressbar(root,
                            orient="horizontal",
                            length=400,
                            mode="indeterminate")
     root.bar.pack()
     asyncio.get_event_loop().create_task(start(root.bar))
     data = list(im.getdata())
     await asyncio.sleep(0.01)
     random.shuffle(data)
     await asyncio.sleep(0.01)
     new_im = Image.new(im.mode, im.size, (255, 255, 255))
     new_im.putdata(data)
     try:
         await root.destroy()
     except Exception:
         pass
     return new_im
Beispiel #5
0
 async def altercolour(self, im: Image.Image):
     data = list(im.getdata())
     max = len(data)
     root = tk.AsyncToplevel(self._master)
     root.title(self._master.cur_locale.general.corruptions.altercolour)
     root.bar = Progressbar(root,
                            orient="horizontal",
                            length=400,
                            mode="determinate",
                            maximum=max)
     root.bar.pack()
     new_data = []
     for r, g, b in data:
         new_data.append((g, b, r))
         root.bar["value"] += 1
         await asyncio.sleep(0.001)
     new_im = Image.new(im.mode, im.size, (255, 255, 255))
     new_im.putdata(new_data)
     try:
         await root.destroy()
     except Exception:
         pass
     return new_im
Beispiel #6
0
            async def new():
                """Internal coroutine used to create the new file dialogue."""
                dialogue = tk.AsyncToplevel(manager)
                dialogue.title(self.cur_locale.menu.fileselect.new)
                dialogue.protocol("WM_DELETE_WINDOW", nothing)
                filename = tk.AsyncEntry(dialogue)
                filename.pack()

                async def cb():
                    if filename.get() != len(filename.get()) * ".":
                        for i in r'\/:*?"<>|':
                            if i in filename.get():
                                button.config(text=self.cur_locale.menu.
                                              fileselect.button.invalid)
                                break
                        else:
                            manager.file = manager.dir / filename.get()
                            await manager.destroy()
                    else:
                        button.config(text=self.cur_locale.menu.fileselect.
                                      button.special)

                # Confirm button
                button = tk.AsyncButton(
                    dialogue,
                    text=self.cur_locale.menu.fileselect.button.default,
                    callback=cb,
                )
                button.pack(fill=tk.X)

                # Cancel button
                tk.AsyncButton(
                    dialogue,
                    text=self.cur_locale.menu.fileselect.button.cancel,
                    callback=dialogue.destroy,
                ).pack(fill=tk.X)
                await manager.wait_window(dialogue)
Beispiel #7
0
    async def file_select(self, *, new_file: bool = True):
        """File select dialogue"""
        manager = tk.AsyncToplevel(self)
        manager.title(self.cur_locale.menu.fileselect.saveas
                      if new_file else self.cur_locale.menu.fileselect.open)
        manager.protocol("WM_DELETE_WINDOW",
                         lambda: asyncio.ensure_future(manager.destroy()))
        dir = pathlib.Path()
        dirbox = tk.AsyncEntry(manager)
        dirbox.grid(row=0, column=0)
        foldermap = tk.AsyncFrame(manager)
        foldermap.grid(row=1, column=0)

        def populate_folder(folder: pathlib.Path):
            """Internally manages the save dialogue."""
            nonlocal dir
            dir = manager.dir
            for i in [".."] + os.listdir(folder):
                if (dir / i).is_file():

                    async def cb(i=i):  # i=i prevents late binding
                        # Late binding causes an undetectable error that
                        # causes all buttons to utilise the same callback
                        manager.file = dir / i
                        await manager.destroy()

                    tk.AsyncButton(
                        foldermap,
                        text=f"{i} {self.cur_locale.menu.fileselect.file}",
                        callback=cb,
                    ).pack(fill=tk.X)
                elif (dir / i).is_dir():

                    async def cb(i=i):  # i=i prevents late binding
                        # Late binding causes an undetectable error that
                        # causes all buttons to utilise the same callback
                        manager.dir = dir / i
                        change_dir(manager.dir)

                    tk.AsyncButton(
                        foldermap,
                        text=f"{i} {self.cur_locale.menu.fileselect.folder}",
                        callback=cb,
                    ).pack(fill=tk.X)

            async def new():
                """Internal coroutine used to create the new file dialogue."""
                dialogue = tk.AsyncToplevel(manager)
                dialogue.title(self.cur_locale.menu.fileselect.new)
                dialogue.protocol("WM_DELETE_WINDOW", nothing)
                filename = tk.AsyncEntry(dialogue)
                filename.pack()

                async def cb():
                    if filename.get() != len(filename.get()) * ".":
                        for i in r'\/:*?"<>|':
                            if i in filename.get():
                                button.config(text=self.cur_locale.menu.
                                              fileselect.button.invalid)
                                break
                        else:
                            manager.file = manager.dir / filename.get()
                            await manager.destroy()
                    else:
                        button.config(text=self.cur_locale.menu.fileselect.
                                      button.special)

                # Confirm button
                button = tk.AsyncButton(
                    dialogue,
                    text=self.cur_locale.menu.fileselect.button.default,
                    callback=cb,
                )
                button.pack(fill=tk.X)

                # Cancel button
                tk.AsyncButton(
                    dialogue,
                    text=self.cur_locale.menu.fileselect.button.cancel,
                    callback=dialogue.destroy,
                ).pack(fill=tk.X)
                await manager.wait_window(dialogue)

            if new_file:
                # New File button
                tk.AsyncButton(foldermap,
                               text=self.cur_locale.menu.fileselect.new,
                               callback=new).pack(fill=tk.X)

        def boxcallback(*i):
            """Internal function called to change the directory to what is typed in dirbox."""
            change_dir(dirbox.get())

        def change_dir(path: typing.Union[str, pathlib.Path]):
            """Internal function to load a path into the file select menu."""
            nonlocal dir, foldermap
            dir = pathlib.Path(path)
            manager.dir = dir
            asyncio.ensure_future(foldermap.destroy())
            foldermap = tk.AsyncFrame(manager)
            foldermap.grid(row=1, column=0)
            populate_folder(dir)
            # Cancel button
            tk.AsyncButton(
                foldermap,
                text=self.cur_locale.menu.fileselect.button.cancel,
                callback=manager.destroy,
            ).pack(fill=tk.X)

        dirbox.bind("<Return>", boxcallback)
        change_dir(".")
        await self.wait_window(manager)
        if hasattr(manager, "file"):
            return manager.file