- Added pencil edit button to player controls - Created EditPopup with drawing layer for image annotation - Drawing tools: color selection (red/blue/green/black), thickness control - Features: undo last stroke, clear all strokes, save edited image - Playback automatically pauses during editing - Only images (.jpg, .jpeg, .png, .bmp) can be edited - Edited images saved with '_edited' suffix in same directory - Drawing layer with touch support for annotations - Full toolbar with color, thickness, and action controls
101 lines
2.9 KiB
Python
101 lines
2.9 KiB
Python
Kiwy drawing
|
|
|
|
from kivy.app import App
|
|
from kivy.uix.boxlayout import BoxLayout
|
|
from kivy.uix.image import Image
|
|
from kivy.uix.button import Button
|
|
from kivy.uix.widget import Widget
|
|
from kivy.graphics import Color, Line
|
|
from kivy.core.window import Window
|
|
|
|
class DrawLayer(Widget):
|
|
def init(self, **kwargs):
|
|
super().init(**kwargs)
|
|
self.strokes = [] # store all drawn lines
|
|
self.current_color = (1, 0, 0) # default red
|
|
self.current_width = 2 # default thickness
|
|
self.drawing_enabled = False # drawing toggle
|
|
|
|
|
|
def on_touch_down(self, touch):
|
|
if not self.drawing_enabled:
|
|
return False
|
|
|
|
with self.canvas:
|
|
Color(*self.current_color)
|
|
new_line = Line(points=[touch.x, touch.y], width=self.current_width)
|
|
self.strokes.append(new_line)
|
|
return True
|
|
|
|
def on_touch_move(self, touch):
|
|
if self.strokes and self.drawing_enabled:
|
|
self.strokes[-1].points += [touch.x, touch.y]
|
|
|
|
# ==========================
|
|
# UNDO LAST LINE
|
|
# ==========================
|
|
def undo(self):
|
|
if self.strokes:
|
|
last = self.strokes.pop()
|
|
self.canvas.remove(last)
|
|
|
|
# ==========================
|
|
# CHANGE COLOR
|
|
# ==========================
|
|
def set_color(self, color_tuple):
|
|
self.current_color = color_tuple
|
|
|
|
# ==========================
|
|
# CHANGE LINE WIDTH
|
|
# ==========================
|
|
def set_thickness(self, value):
|
|
self.current_width = value
|
|
class EditorUI(BoxLayout):
|
|
def init(self, **kwargs):
|
|
super().init(orientation="vertical", **kwargs)
|
|
|
|
|
|
# Background image
|
|
self.img = Image(source="graph.png", allow_stretch=True)
|
|
self.add_widget(self.img)
|
|
|
|
# Drawing layer above image
|
|
self.draw = DrawLayer()
|
|
self.add_widget(self.draw)
|
|
|
|
# Toolbar
|
|
toolbar = BoxLayout(size_hint_y=0.15)
|
|
|
|
toolbar.add_widget(Button(text="Draw On", on_press=self.toggle_draw))
|
|
toolbar.add_widget(Button(text="Red", on_press=lambda x: self.draw.set_color((1,0,0))))
|
|
toolbar.add_widget(Button(text="Blue", on_press=lambda x: self.draw.set_color((0,0,1))))
|
|
toolbar.add_widget(Button(text="Green", on_press=lambda x: self.draw.set_color((0,1,0))))
|
|
|
|
toolbar.add_widget(Button(text="Thin", on_press=lambda x: self.draw.set_thickness(2)))
|
|
toolbar.add_widget(Button(text="Thick", on_press=lambda x: self.draw.set_thickness(6)))
|
|
|
|
toolbar.add_widget(Button(text="Undo", on_press=lambda x: self.draw.undo()))
|
|
toolbar.add_widget(Button(text="Save", on_press=lambda x: self.save_image()))
|
|
|
|
self.add_widget(toolbar)
|
|
|
|
# ==========================
|
|
# TOGGLE DRAWING MODE
|
|
# ==========================
|
|
def toggle_draw(self, btn):
|
|
self.draw.drawing_enabled = not self.draw.drawing_enabled
|
|
btn.text = "Draw Off" if self.draw.drawing_enabled else "Draw On"
|
|
|
|
# ==========================
|
|
# SAVE MERGED IMAGE
|
|
# ==========================
|
|
def save_image(self):
|
|
self.export_to_png("edited_graph.png")
|
|
print("Saved as edited_graph.png")
|
|
class AnnotatorApp(App):
|
|
def build(self):
|
|
return EditorUI()
|
|
|
|
AnnotatorApp().run()
|
|
|