วิธีสร้างแอปพลิเคชัน Paint โดยใช้ Python
เครื่องมือระบายสีแบบง่ายๆ เป็นหนึ่งในแอพทั่วไปที่คุณพบได้ในคอมพิวเตอร์ส่วนใหญ่ ช่วยให้ศิลปินทำผิดพลาดโดยไม่ต้องกลัว เลือกสีใดก็ได้ด้วยการคลิกปุ่ม และเปลี่ยนขนาดฝีแปรงได้ทันที คุณสามารถใช้มันเพื่อสร้างโลโก้แบรนด์ สร้างแนวคิดให้กับอินเทอร์เฟซผู้ใช้ และใส่คำอธิบายประกอบไดอะแกรม
เราสามารถสร้างโปรแกรมซอฟต์แวร์วาดภาพในลักษณะใดได้บ้าง?
โมดูล Tkinter และหมอน
ในการพัฒนาแอพพลิเคชั่นการลงสีโดยใช้ Python จำเป็นต้องติดตั้งทั้งโมดูล Tkinter และ Pillow ในระบบ เฟรมเวิร์ก Tkinter เป็นหนึ่งในตัวเลือกยอดนิยมเมื่อพูดถึงการออกแบบอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI) สำหรับแอปพลิเคชันเดสก์ท็อปที่ใช้ Python เฟรมเวิร์กนี้มีวิดเจ็ตในตัวที่หลากหลาย เช่น ป้ายกำกับ กล่องข้อความ แคนวาส และปุ่มที่ช่วยให้นักพัฒนาสามารถสร้างอินเทอร์เฟซแบบโต้ตอบที่ดึงดูดสายตาได้อย่างรวดเร็วและง่ายดาย
Pillow ซึ่งเป็นอนุพันธ์ของ Python Imaging Library (PIL) ที่มีชื่อเสียง ทำหน้าที่เป็นชุดเครื่องมือประมวลผลภาพอเนกประสงค์สำหรับแอปพลิเคชัน Python ด้วยการใช้ประโยชน์จากความสามารถ ผู้ใช้จึงสามารถดำเนินการต่างๆ บนสื่อภาพดิจิทัล เช่น การเปิด การปรับขนาด การหมุน และการครอบตัดรูปภาพได้อย่างง่ายดาย นอกจากนี้ ไลบรารีนี้ยังอำนวยความสะดวกในการแปลงรูปแบบ ช่วยให้สามารถพัฒนาอัลกอริธึมที่ซับซ้อน เช่น ระบบแนะนำสูตรอาหาร และมอบฟังก์ชันในการดึงรูปภาพจากฐานข้อมูลแบบสุ่ม
หากต้องการติดตั้งโมดูลเหล่านี้ ให้รัน:
pip install tk pillow
กำหนดโครงสร้างของแอปพลิเคชัน Paint
ซอร์สโค้ดที่สมบูรณ์สำหรับโปรเจ็กต์นี้มีอยู่ในพื้นที่เก็บข้อมูล GitHub ของเรา ซึ่งคุณสามารถเข้าถึงได้โดยไปที่ URL ดังกล่าว
ในการเริ่มต้น เราจะนำเข้าโมดูลที่จำเป็น ต่อจากนั้น เราจะสร้างอินสแตนซ์ของคลาส DrawApp
ตั้งค่าคุณสมบัติ เช่น ชื่อเรื่องของหน้าต่าง สีตัวชี้ และสีของยางลบ นอกจากนี้ เรายังจะตรวจสอบให้แน่ใจด้วยว่าแอปพลิเคชันเปิดในโหมดเต็มหน้าจอโดยเรียกใช้เมธอด setup\_widgets()
import tkinter as tk
from tkinter.ttk import Scale
from tkinter import colorchooser, filedialog, messagebox
import PIL.ImageGrab as ImageGrab
class DrawApp:
def __init__(self, root):
self.root = root
self.root.title("Kids' Paint App")
self.root.attributes("-fullscreen", True)
self.pointer = "black"
self.erase = "white"
self.setup_widgets()
ในการสร้างอินเทอร์เฟซกับวิดเจ็ต ให้สร้างฟังก์ชันชื่อ setup\_widgets
ภายในฟังก์ชันนี้ ให้สร้างส่วนประกอบที่มีป้ายกำกับซึ่งแสดงชื่อเรื่องโดยระบุความสัมพันธ์ระหว่างผู้ปกครอง ข้อความที่จะแสดง การกำหนดค่าแบบอักษร สีฉากหลัง และเฉดสีของเนื้อหาที่เป็นข้อความ นอกจากนี้ สร้างกรอบงานรอบๆ แผงการเลือกสีโดยมอบหมายความรับผิดชอบ เช่น การกำหนดองค์ประกอบหลัก คำจารึกที่จะแสดง การตั้งค่าแบบอักษร และขนาดเส้นขอบ สุดท้าย กำหนดค่าขอบเขตด้วยชุดลูกคลื่นและตั้งค่าโทนสีพื้นหลังให้เป็นสีขาว
def setup_widgets(self):
self.title_label = tk.Label(
self.root,
text="Kids' Paint App",
font=("Comic Sans MS", 30),
bg="lightblue",
fg="purple",
)
self.title_label.pack(fill=tk.X, pady=10)
self.color_frame = tk.LabelFrame(
self.root,
text="Colors",
font=("Comic Sans MS", 15),
bd=5,
relief=tk.RIDGE,
bg="white",
)
self.color_frame.place(x=10, y=80, width=90, height=180)
สร้างรายการเพื่อกำหนดชุดสีสำหรับชุดสี ใช้การวนซ้ำเพื่อสร้างปุ่มสำหรับแต่ละสี โดยคำนึงถึงค่า RGB ที่สอดคล้องกัน ระบุคอนเทนเนอร์หลัก สีพื้นหลัง ความหนาของเส้นขอบ คุณสมบัติรูปแบบ และความกว้างสำหรับทุกปุ่ม นอกจากนี้ ให้สร้างการดำเนินการที่จะดำเนินการเมื่อคลิกที่แต่ละรายการ จัดเรียงส่วนประกอบทั้งหมดโดยใช้ระยะขอบที่เหมาะสมและจัดระเบียบสีเป็นคู่
colors = [
"blue",
"red",
"green",
"orange",
"violet",
"black",
"yellow",
"purple",
"pink",
"gold",
"brown",
"indigo",
]
i, j = 0, 0
for color in colors:
tk.Button(
self.color_frame,
bg=color,
bd=2,
relief=tk.RIDGE,
width=3,
command=lambda col=color: self.select_color(col),
).grid(row=i, column=j, padx=2, pady=2)
i \+= 1
if i == 4:
i = 0
j = 1
ในทำนองเดียวกัน ให้เราแยกแยะปุ่มต่างๆ สำหรับยางลบ ปุ่มหนึ่งสำหรับทำความสะอาดจอแสดงผล และอีกปุ่มหนึ่งเพื่อรักษาภาพประกอบไว้
self.eraser_btn = tk.Button(
self.root,
text="Eraser",
bd=4,
bg="white",
command=self.eraser,
width=9,
relief=tk.RIDGE,
font=("Comic Sans MS", 12),
)
self.eraser_btn.place(x=10, y=310)
self.clear_screen_btn = tk.Button(
self.root,
text="Clear Screen",
bd=4,
bg="white",
command=self.clear_screen,
width=12,
relief=tk.RIDGE,
font=("Comic Sans MS", 12),
)
self.clear_screen_btn.place(x=10, y=370)
self.save_as_btn = tk.Button(
self.root,
text="Save Drawing",
bd=4,
bg="white",
command=self.save_as,
width=12,
relief=tk.RIDGE,
font=("Comic Sans MS", 12),
)
self.save_as_btn.place(x=10, y=430)
self.bg_btn = tk.Button(
self.root,
text="Background",
bd=4,
bg="white",
command=self.canvas_color,
width=12,
relief=tk.RIDGE,
font=("Comic Sans MS", 12),
)
self.bg_btn.place(x=10, y=490)
self.pointer_frame = tk.LabelFrame(
self.root,
text="Size",
bd=5,
bg="white",
font=("Comic Sans MS", 15, "bold"),
relief=tk.RIDGE,
)
ในการสร้างวิดเจ็ตมาตราส่วนที่กำหนดเองซึ่งสามารถปรับขนาดของทั้งตัวชี้และยางลบภายในช่วงและความยาวพิกเซลที่ระบุได้ จำเป็นต้องกำหนดวิดเจ็ตมาตราส่วน วิดเจ็ตนี้ควรได้รับองค์ประกอบหลัก การวางแนว และช่วงเป็นพิกเซล รวมถึงความยาวของแถบเลื่อน นอกจากนี้ การรวมองค์ประกอบ Canvas เข้ากับพาเรนต์ สีพื้นหลัง ความกว้างของเส้นขอบ และการนูนร่องที่มีขนาดเฉพาะจะเป็นประโยชน์
วางตำแหน่งผืนผ้าใบในพิกัดที่เหมาะสมและกำหนดค่าการยึดไว้ที่มุมตะวันตกเฉียงเหนือ (ขอบซ้ายบน) จากนั้น เชื่อมโยงตัวจัดการเหตุการณ์ B1-Motion กับฟังก์ชันการทาสีที่กำหนด ในบริบทนี้ “B1” หมายถึงสถานะการกดของปุ่มซ้ายของเมาส์ ในขณะที่ “การเคลื่อนไหว” หมายถึงการเคลื่อนไหวที่ตามมาซึ่งเกิดจากการป้อนข้อมูลของผู้ใช้ โดยพื้นฐานแล้ว การใช้การตั้งค่านี้ทำให้สามารถติดตามการเคลื่อนไหวของเมาส์ได้ในขณะที่กดปุ่มซ้ายอย่างต่อเนื่อง
self.pointer_frame.place(x=10, y=580, height=150, width=70)
self.pointer_size = Scale(
self.pointer_frame, orient=tk.VERTICAL, from_=48, to=1, length=120
)
self.pointer_size.set(1)
self.pointer_size.grid(row=0, column=1, padx=15)
self.canvas = tk.Canvas(
self.root, bg="white", bd=5, relief=tk.GROOVE, height=650, width=1300
)
self.canvas.place(x=160, y=120, anchor="nw")
self.canvas.bind("<B1-Motion>", self.paint)
กำหนดคุณสมบัติของแอพพลิเคชั่น Paint
เพื่อดำเนินการกระบวนการพ่นสีภายในแอปพลิเคชันของเรา เราได้นำวิธีการที่เรียกว่า"สี"มาใช้ วิธีการนี้เกี่ยวข้องกับการวาดรูปวงรีเล็กๆ บนหน้าจออย่างต่อเนื่อง เพื่อให้บรรลุเป้าหมายนี้ เราคำนวณมุมซ้ายบนของแต่ละวงรีโดยการลบสองออกจากพิกัด X และ Y ของเหตุการณ์เมาส์ล่าสุด ในทางกลับกัน มุมขวาล่างถูกกำหนดโดยการเพิ่มสองค่าตามลำดับของ X และ Y ท้ายที่สุด ขอบเขตเหล่านี้จะกำหนดรูปร่างของวงรีที่จะถูกสร้างขึ้นสำหรับทุกเฟรมที่ตามมาจนกว่าจะมีประกาศเพิ่มเติม
ปรับสีเติม สีเค้าร่าง และความหนาของเส้นตามที่ผู้ใช้เลือกสำหรับเคอร์เซอร์
def paint(self, event):
x1, y1 = (event.x-2), (event.y-2)
x2, y2 = (event.x \+ 2), (event.y \+ 2)
self.canvas.create_oval(
x1,
y1,
x2,
y2,
fill=self.pointer,
outline=self.pointer,
width=self.pointer_size.get(),
)
select\_color
, ยางลบ
และ clear\_screen
แต่ละวิธีมีจุดประสงค์เฉพาะของตนเองในการจัดการลักษณะที่ปรากฏและเนื้อหาของผืนผ้าใบ ฟังก์ชัน select\_color
ยอมรับอาร์กิวเมนต์เดียวที่แสดงถึงค่าสีเฉพาะ ซึ่งจากนั้นจะใช้เพื่อตั้งค่าสีปัจจุบันที่วาดโดยตัวชี้ ช่วยให้สามารถเลือกสีต่างๆ ได้ง่ายตามต้องการ.pythondef select_color(self, color):self.selected_color=colorถัดไป เรามีฟังก์ชัน ยางลบ
ซึ่งต้องการพารามิเตอร์อินพุตเพียงตัวเดียวด้วย มีหน้าที่สร้างเอฟเฟกต์ “ยางลบ” เมื่อวาดภาพบนผืนผ้าใบ ส่งผลให้ได้เส้นกึ่งโปร่งใสที่ผสมผสานกัน
def select_color(self, col):
self.pointer = col
def eraser(self):
self.pointer = self.erase
def clear_screen(self):
self.canvas.delete("all")
รวมฟังก์ชันการทำงานที่ได้รับจากเมธอด canvas\_color
เข้ากับคลาส TurtleScreen
โดยจะเปิดตัวเลือกสีที่แสดงเฉดสีต่างๆ เพื่อให้ผู้ใช้เลือก เมื่อเลือกตัวเลือกแล้ว ให้ใช้วิธีการ กำหนดค่า
เพื่อสร้างสีพื้นหลังของผืนผ้าใบ จากนั้นจึงใช้สีนี้กับลักษณะของยางลบ
def canvas_color(self):
color = colorchooser.askcolor()
if color:
self.canvas.configure(background=color[1])
self.erase = color[1]
รวมขั้นตอนที่ให้ไว้ในการตอบกลับภาษาอังกฤษที่สวยงาม: “กำหนดวิธีการที่เรียกว่า’บันทึก\_as’ซึ่งจะแจ้งให้ผู้ใช้เลือกชื่อไฟล์และตำแหน่งสำหรับบันทึกภาพหน้าจอที่บันทึกไว้ ใช้คลาส ImageGrab ของ Pillow เพื่อยึดทั้งหน้าจอโดยการนำเสนอกล่องโต้ตอบไฟล์ เมื่อเลือกแล้ว ให้ใช้เทคนิคการครอบตัดโดยใช้พิกัดที่ระบุเพื่อให้ได้ขอบเขตผืนผ้าใบที่ต้องการ ปรับพิกัดซ้ำๆ ตามความจำเป็นเพื่อให้ได้พื้นที่เฉพาะที่สนใจ
แน่นอน! นี่คือความพยายามของฉันในการถอดความโค้ดของคุณในภาษาที่เป็นทางการมากขึ้น: pythondef save_image(filepath):try:p=PILImage.create(filename=filepath)if isinstance(p, ImageGrab.InvalidGrab):raise Exception(“Failed to load the image” )# บันทึกรูปภาพและแสดงข้อความยืนยัน boxp.save(str(filepath))tkinter.messagebox.showinfo(‘Success’,‘The image has been Saved’)ยกเว้นข้อยกเว้นเป็น e:# จัดการข้อยกเว้นและแสดงข้อความแสดงข้อผิดพลาด boxtkinter.messagebox.showerror(‘ข้อผิดพลาด’, str(e))
def save_as(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".jpg", filetypes=[("Image files", "*.jpg")]
)
if file_path:
try:
y = 148
x = 200
y1 = 978
x1 = 1840
ImageGrab.grab().crop((x, y, x1, y1)).save(file_path)
messagebox.showinfo("Save Drawing", "Image file saved successfully!")
except Exception as e:
messagebox.showerror("Error", f"Failed to save the image file: {e}")
ใช้ความสามารถของโมดูล Tkinter โดยการสร้างอินสแตนซ์ของทั้งคลาส Tk และ DrawApp ในขณะที่ใช้ประโยชน์จากฟังก์ชันการทำงานที่ได้รับจากวิธี mainloop เพื่อเริ่มต้นลูปเหตุการณ์ Tkinter และตรวจสอบการโต้ตอบของผู้ใช้กับอินเทอร์เฟซแบบกราฟิกอย่างต่อเนื่องจนกว่าจะปิด
if __name__ == "__main__":
root = tk.Tk()
app = DrawApp(root)
root.mainloop()
การทดสอบคุณสมบัติการวาดภาพที่แตกต่างกันโดยใช้ Python
เมื่อเรียกใช้แอปพลิเคชัน Paint ผู้ใช้จะเห็นอินเทอร์เฟซผู้ใช้แบบกราฟิกที่มีเครื่องมือเลือกสี ปุ่มฟังก์ชันสี่ปุ่ม ตัวควบคุมการปรับแบบเลื่อน และพื้นผิวผ้าใบเปล่าสำหรับสร้างงานศิลปะ:
เลือกเฉดสีโดยคลิกที่สี จากนั้นใช้ปุ่มคลิกซ้ายของเมาส์เพื่อสร้างงานศิลปะภายในเฉดสีที่เลือกไว้บนพื้นผิวผ้าใบ:
เมื่อคลิกที่ตัวเลือก"ยางลบ"และเลื่อนแถบเลื่อนแนวตั้งไปในทิศทางขึ้น คุณสามารถเลือกที่จะขยายเครื่องมือยางลบได้ หากต้องการทดสอบฟังก์ชันการทำงาน เพียงวาดด้วยแปรงที่เลือก จากนั้นใช้ยางลบเพื่อลบเส้นออกจากงานศิลปะของคุณ
เมื่อคลิกที่ตัวเลือก"ล้างหน้าจอ"ซอฟต์แวร์จะลบอาร์ตเวิร์คที่ดำเนินการก่อนหน้านี้ทั้งหมด หากต้องการปรับเปลี่ยนเฉดสีฉากหลัง โปรดแตะที่แท็บ"พื้นหลัง"ซึ่งจะแสดงสเปกตรัมของสีให้เลือก
เมื่อเลือกตัวเลือก"บันทึกภาพวาด"หน้าต่างจะปรากฏขึ้นเพื่อให้คุณสามารถเลือกตำแหน่งที่ต้องการและกำหนดชื่อเรื่องให้กับไฟล์ที่คุณบันทึกไว้ ซอฟต์แวร์จะจัดเก็บไฟล์ไว้ในไดเร็กทอรีที่ระบุโดยอัตโนมัติ
การปรับปรุงแอปพลิเคชั่น Paint
เพื่อเพิ่มความอเนกประสงค์ของซอฟต์แวร์การลงสี ขอแนะนำให้นำคุณสมบัติมาใช้ซึ่งจะช่วยให้ผู้ใช้รวมรูปทรงเรขาคณิตไว้ในอาร์ตเวิร์คของตนได้ นอกจากนี้ การให้ตัวเลือกสำหรับการเลือกสไตล์แปรงและการตั้งค่าความโปร่งใสจะช่วยเพิ่มขีดความสามารถของโปรแกรมให้ดียิ่งขึ้น นอกจากนี้ การรวมฟังก์ชันที่ทำให้สามารถแทรกข้อความและสติ๊กเกอร์กราฟิกอาจเป็นประโยชน์ในการขยายขอบเขตของการสร้างสรรค์ที่เป็นไปได้ สุดท้ายนี้ การรวมคุณสมบัติต่างๆ เช่น ความสามารถในการเลิกทำ ทำซ้ำ ปรับขนาด หรือหมุนภาพ จะช่วยปรับปรุงกระบวนการวาดโดยรวมได้อย่างมาก
เพื่อสร้างองค์ประกอบภาพต่างๆ เป็นไปได้ที่จะใช้เทคนิคต่างๆ โดยใช้วิธี create\_rectangle, create\_oval, create\_line และ create\_polygon นอกจากนี้ สำหรับการรวมเนื้อหาหรือรูปภาพที่เป็นลายลักษณ์อักษร เราอาจใช้ฟังก์ชัน create\_text และ create\_image นอกจากนี้ หากต้องการ คุณสามารถใช้ฟังก์ชันการปรับขนาดและการย้ายตำแหน่งของ Pillow เพื่อเปลี่ยนขนาดและการวางแนวของรูปภาพได้