Python使用PIL構(gòu)建圖片裁剪工具的實(shí)現(xiàn)步驟
C:\pythoncode\new\cropimageandsave.py
功能特性
圖片加載:支持加載 JPG 和 PNG 格式的圖片。
動(dòng)態(tài)裁剪:通過(guò)鼠標(biāo)繪制矩形選擇框進(jìn)行裁剪。
縮放適配:圖片會(huì)根據(jù)面板大小自動(dòng)縮放顯示。
保存裁剪結(jié)果:裁剪后的圖片可以保存為 PNG 文件。
代碼實(shí)現(xiàn)
完整代碼如下:
import wx
import os
from PIL import Image
class ImageCropperFrame(wx.Frame):
def __init__(self):
super().__init__(parent=None, title='圖片裁剪工具', size=(800, 600))
self.init_ui()
def init_ui(self):
# 創(chuàng)建菜單欄
menubar = wx.MenuBar()
file_menu = wx.Menu()
open_item = file_menu.Append(wx.ID_OPEN, '打開(kāi)圖片', '打開(kāi)一個(gè)圖片文件')
menubar.Append(file_menu, '文件')
self.SetMenuBar(menubar)
# 創(chuàng)建面板和圖片顯示控件
self.panel = wx.Panel(self)
self.image_panel = wx.Panel(self.panel)
self.image_panel.SetBackgroundColour(wx.Colour(200, 200, 200))
# 初始化變量
self.image = None
self.bitmap = None
self.start_pos = None
self.current_pos = None
self.is_drawing = False
# 設(shè)置布局
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.image_panel, 1, wx.EXPAND)
self.panel.SetSizer(sizer)
# 綁定事件
self.Bind(wx.EVT_MENU, self.on_open, open_item)
self.image_panel.Bind(wx.EVT_PAINT, self.on_paint)
self.image_panel.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
self.image_panel.Bind(wx.EVT_LEFT_UP, self.on_left_up)
self.image_panel.Bind(wx.EVT_MOTION, self.on_motion)
def on_open(self, event):
# 打開(kāi)文件對(duì)話框
with wx.FileDialog(self, "選擇圖片文件",
wildcard="圖片文件 (*.jpg;*.jpeg;*.png)|*.jpg;*.jpeg;*.png",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return
# 加載圖片
pathname = fileDialog.GetPath()
self.load_image(pathname)
self.image_path = pathname
def load_image(self, path):
# 使用PIL加載圖片
self.pil_image = Image.open(path)
# 轉(zhuǎn)換為wx.Bitmap
self.image = wx.Image(path, wx.BITMAP_TYPE_ANY)
# 調(diào)整圖片大小以適應(yīng)窗口
self.scale_image()
self.Refresh()
def scale_image(self):
# 獲取面板大小
panel_size = self.image_panel.GetSize()
# 計(jì)算縮放比例
width_ratio = panel_size.width / self.image.GetWidth()
height_ratio = panel_size.height / self.image.GetHeight()
scale = min(width_ratio, height_ratio)
# 縮放圖片
new_width = int(self.image.GetWidth() * scale)
new_height = int(self.image.GetHeight() * scale)
self.image = self.image.Scale(new_width, new_height)
self.bitmap = wx.Bitmap(self.image)
# 保存縮放比例用于裁剪
self.scale_factor = scale
def on_paint(self, event):
dc = wx.PaintDC(self.image_panel)
if self.bitmap:
dc.DrawBitmap(self.bitmap, 0, 0)
# 繪制選擇框
if self.start_pos and self.current_pos:
dc.SetPen(wx.Pen(wx.RED, 1, wx.PENSTYLE_DOT))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
x = min(self.start_pos[0], self.current_pos[0])
y = min(self.start_pos[1], self.current_pos[1])
w = abs(self.current_pos[0] - self.start_pos[0])
h = abs(self.current_pos[1] - self.start_pos[1])
dc.DrawRectangle(x, y, w, h)
def on_left_down(self, event):
self.start_pos = event.GetPosition()
self.current_pos = self.start_pos
self.is_drawing = True
def on_motion(self, event):
if self.is_drawing:
self.current_pos = event.GetPosition()
self.Refresh()
def on_left_up(self, event):
if self.is_drawing:
self.is_drawing = False
# 獲取選擇區(qū)域
x1 = min(self.start_pos[0], self.current_pos[0])
y1 = min(self.start_pos[1], self.current_pos[1])
x2 = max(self.start_pos[0], self.current_pos[0])
y2 = max(self.start_pos[1], self.current_pos[1])
# 轉(zhuǎn)換回原始圖片坐標(biāo)
orig_x1 = int(x1 / self.scale_factor)
orig_y1 = int(y1 / self.scale_factor)
orig_x2 = int(x2 / self.scale_factor)
orig_y2 = int(y2 / self.scale_factor)
# 裁剪圖片
cropped = self.pil_image.crop((orig_x1, orig_y1, orig_x2, orig_y2))
# 生成保存路徑
directory = os.path.dirname(self.image_path)
filename = os.path.splitext(os.path.basename(self.image_path))[0]
save_path = os.path.join(directory, f"{filename}_cropped.png")
# 保存裁剪后的圖片
cropped.save(save_path)
# 顯示成功消息
wx.MessageBox(f"裁剪后的圖片已保存至:\n{save_path}",
"保存成功",
wx.OK | wx.ICON_INFORMATION)
# 重置選擇區(qū)域
self.start_pos = None
self.current_pos = None
self.Refresh()
if __name__ == '__main__':
app = wx.App()
frame = ImageCropperFrame()
frame.Show()
app.MainLoop()核心實(shí)現(xiàn)
圖片加載與縮放
使用 PIL.Image 加載圖片,并通過(guò) wx.Image 將其轉(zhuǎn)換為適配 wxPython 的格式。同時(shí),通過(guò)計(jì)算縮放比例,確保圖片適配顯示區(qū)域。
繪制矩形選擇框
利用 wx.PaintDC 繪制矩形選擇框,在鼠標(biāo)事件(按下、移動(dòng)、釋放)中動(dòng)態(tài)更新選擇框。
裁剪與保存
通過(guò) PIL.Image.crop 方法,根據(jù)用戶選擇的區(qū)域裁剪圖片,并自動(dòng)生成裁剪后的文件路徑進(jìn)行保存。
運(yùn)行結(jié)果


總結(jié)
此工具簡(jiǎn)單實(shí)用,能夠快速完成圖片裁剪任務(wù)。您可以根據(jù)實(shí)際需求進(jìn)一步擴(kuò)展,例如添加更多格式支持或多圖片批量裁剪功能。歡迎嘗試并提出您的建議!
到此這篇關(guān)于Python使用PIL構(gòu)建圖片裁剪工具的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)Python PIL圖片裁剪工具內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python+Selenium+Webdriver實(shí)現(xiàn)自動(dòng)執(zhí)行微軟獎(jiǎng)勵(lì)積分腳本
這篇文章主要為大家詳細(xì)介紹了如何利用Python+Selenium+Webdriver實(shí)現(xiàn)自動(dòng)執(zhí)行微軟獎(jiǎng)勵(lì)積分腳本,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-02-02
AI對(duì)話中的“停止生成”與“重新回答”交互邏輯和實(shí)現(xiàn)方法
在AI應(yīng)用開(kāi)發(fā)中,我們往往沉迷于Prompt的調(diào)優(yōu)和RAG架構(gòu)的設(shè)計(jì),卻忽視了交互層面的工程細(xì)節(jié),實(shí)現(xiàn)“停止”與“重試”看似是前端的小功能,實(shí)則是對(duì)Web應(yīng)用狀態(tài)管理能力的考驗(yàn),從商業(yè)價(jià)值角度看,這兩個(gè)功能直接關(guān)聯(lián)成本與體驗(yàn)2026-02-02
Python實(shí)現(xiàn)繁體轉(zhuǎn)簡(jiǎn)體功能的三種方案
在中文信息處理中,繁體字與簡(jiǎn)體字的轉(zhuǎn)換是一個(gè)常見(jiàn)需求,無(wú)論是處理港澳臺(tái)地區(qū)的文本數(shù)據(jù),還是開(kāi)發(fā)面向不同中文用戶群體的應(yīng)用,繁簡(jiǎn)轉(zhuǎn)換都是不可或缺的功能,本文將詳細(xì)介紹如何在Python中實(shí)現(xiàn)高效準(zhǔn)確的繁體轉(zhuǎn)簡(jiǎn)體功能,需要的朋友可以參考下2025-11-11
python實(shí)現(xiàn)自動(dòng)化的sql延時(shí)注入
這篇文章主要為大家詳細(xì)介紹了如何基于python實(shí)現(xiàn)自動(dòng)化的sql延時(shí)注入腳本,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12
Python時(shí)間處理模塊time和datetime詳解
本文詳細(xì)介紹了Python中常用的時(shí)間處理模塊time和datetime,time模塊提供多種時(shí)間獲取和轉(zhuǎn)換功能,datetime模塊則在time的基礎(chǔ)上增加了日期和時(shí)間的組合處理,如datetime.now()獲取當(dāng)前日期時(shí)間,兩個(gè)模塊在日常編程中非常有用,尤其是在需要時(shí)間日期計(jì)算和轉(zhuǎn)換的場(chǎng)景下2024-10-10
matlab調(diào)用python的各種方法舉例子詳解
為了發(fā)揮matlab的繪圖優(yōu)勢(shì)+原先python寫好的功能組合方式,下面這篇文章主要給大家介紹了關(guān)于matlab調(diào)用python的各種方法,需要的朋友可以參考下2023-09-09
Python使用DPKT實(shí)現(xiàn)分析數(shù)據(jù)包
dpkt項(xiàng)目是一個(gè)Python模塊,主要用于對(duì)網(wǎng)絡(luò)數(shù)據(jù)包進(jìn)行解析和操作,z這篇文章主要為大家介紹了python如何利用DPKT實(shí)現(xiàn)分析數(shù)據(jù)包,有需要的可以參考下2023-10-10
python實(shí)現(xiàn)順序表的簡(jiǎn)單代碼
這篇文章主要為大家詳細(xì)介紹了順序表定義及python實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09

