JustPaste.it

ReTextureMe Version 1

import tkinter as tk
from tkinter import filedialog, colorchooser
from PIL import Image, ImageTk

class PixelEditor:
    def __init__(self, root):
        self.root = root
        self.scale = 20
        self.image = Image.new("RGBA", (16, 16), (0,0,0,0))
        self.history = []
        self.future = []
        self.color = (0,0,0,255)
        self.tool = "pen"
        self.dark = True

        self.canvas = tk.Canvas(root, width=320, height=320, highlightthickness=0)
        self.canvas.pack()

        self.canvas.bind("<B1-Motion>", self.paint)
        self.canvas.bind("<Button-1>", self.paint)
        self.canvas.bind("<Button-3>", self.pick_from_canvas)

        self.setup_ui()
        self.apply_theme()
        self.draw()

    def setup_ui(self):
        self.frame = tk.Frame(self.root)
        self.frame.pack(fill="x")

        tk.Button(self.frame, text="Load", command=self.load).pack(side="left")
        tk.Button(self.frame, text="Save", command=self.save).pack(side="left")
        tk.Button(self.frame, text="Color", command=self.pick_color).pack(side="left")
        tk.Button(self.frame, text="Pen", command=lambda: self.set_tool("pen")).pack(side="left")
        tk.Button(self.frame, text="Eraser", command=lambda: self.set_tool("eraser")).pack(side="left")
        tk.Button(self.frame, text="Undo", command=self.undo).pack(side="left")
        tk.Button(self.frame, text="Redo", command=self.redo).pack(side="left")
        tk.Button(self.frame, text="Theme", command=self.toggle_theme).pack(side="left")

    def apply_theme(self):
        bg = "#1e1e1e" if self.dark else "#eeeeee"
        fg = "#ffffff" if self.dark else "#000000"
        self.root.configure(bg=bg)
        self.frame.configure(bg=bg)
        for w in self.frame.winfo_children():
            w.configure(bg=bg, fg=fg, activebackground=bg, activeforeground=fg)
        self.canvas.configure(bg="#2b2b2b" if self.dark else "#ffffff")

    def toggle_theme(self):
        self.dark = not self.dark
        self.apply_theme()

    def set_tool(self, tool):
        self.tool = tool

    def pick_color(self):
        c = colorchooser.askcolor()[0]
        if c:
            self.color = (int(c[0]), int(c[1]), int(c[2]), 255)

    def pick_from_canvas(self, event):
        x = event.x // self.scale
        y = event.y // self.scale
        if 0 <= x < self.image.width and 0 <= y < self.image.height:
            self.color = self.image.getpixel((x, y))

    def paint(self, event):
        x = event.x // self.scale
        y = event.y // self.scale

        if 0 <= x < self.image.width and 0 <= y < self.image.height:
            self.history.append(self.image.copy())
            self.future.clear()

            if self.tool == "pen":
                self.image.putpixel((x, y), self.color)
            else:
                self.image.putpixel((x, y), (0,0,0,0))

            self.draw()

    def draw(self):
        preview = self.image.resize(
            (self.image.width*self.scale, self.image.height*self.scale),
            Image.NEAREST
        )
        self.tk_img = ImageTk.PhotoImage(preview)
        self.canvas.delete("all")
        self.canvas.create_image(0,0,anchor="nw",image=self.tk_img)

    def load(self):
        path = filedialog.askopenfilename(filetypes=[("PNG","*.png")])
        if path:
            self.image = Image.open(path).convert("RGBA")
            self.draw()

    def save(self):
        path = filedialog.asksaveasfilename(defaultextension=".png")
        if path:
            self.image.save(path, "PNG")

    def undo(self):
        if self.history:
            self.future.append(self.image.copy())
            self.image = self.history.pop()
            self.draw()

    def redo(self):
        if self.future:
            self.history.append(self.image.copy())
            self.image = self.future.pop()
            self.draw()

root = tk.Tk()
root.title("Pixel Editor")
PixelEditor(root)
root.mainloop()

rtm.png