GUI采用wxPython,图像处理采用opencv,制作了一款简单的图片处理工具。其效果如下
主要的功能及实现
选中文件资源管理器中的图片
这个采用tkinter库的filedialog模块很容易实现
image_path = filedialog.askopenfilename(initialdir=r"..\\", title="select an image whose filename endwiths .jpg/png",filetypes=[ ("JPG", ".jpg"),("PNG", ".png")])
参数一:initialdir是打开文件资源管理器的初始路径,可以不设置
参数二: title是打开的文件资源管理器的最左上方的标题
参数三: filetypes,比如我上面的设置过滤掉了其他非.jpg
、.png
文件
askopenfilename的返回值就是你选择的文件路径
图像处理
我主要加了图片涂鸦、图片黑白化、图片裁剪这几个功能,具体效果参考最上面的效果图,实现的话算法+业务逻辑很容易
算法算是比较简单的算法,但是业务逻辑和其中不少的坑是只有动手后才能深有体会的,这里贴出这部分的主要代码:
def OnImageGrayClicked(self,event):
if self.isLoaded == True:
dlg = wx.MessageDialog(self, u"this Operation cannot be undo", u"Warning", wx.YES_NO)
value = dlg.ShowModal()
if value == wx.ID_YES:
self.setImage(cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY))
self.editMenu.Check(ID_IMAGE_GRAY, True)
self.image_gray.Enable(False)
else:
self.editMenu.Check(ID_IMAGE_GRAY, False)
dlg.Destroy()
else:
wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()
self.editMenu.Check(ID_IMAGE_GRAY, False)
def OnImageDrawClicked(self,event):
if self.isLoaded == True:
self.canDraw = not self.canDraw
if self.canDraw == True:
self.image_draw.SetItemLabel("disabel drawing on the image")
self.image_cut.Enable(False)
else:
self.image_draw.SetItemLabel("enabel drawing on the image")
self.image_cut.Enable(True)
pass
else:
wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()
def OnImageCutClicked(self,event):
if self.isLoaded == True:
self.canCut = not self.canCut
if self.canCut == True:
self.image_copy = self.image.copy()
self.image_cut.SetItemLabel("disabel cutting on the image")
self.image_draw.Enable(False)
else:
self.image_cut.SetItemLabel("enabel cutting on the image")
self.image_draw.Enable(True)
return
else:
wx.MessageDialog(self, u"please make sure you have loaded the image successfully", u"Warning", wx.OK).ShowModal()
def OnSettingsLineWeightClicked(self,event):
self.lineWeight = wx.GetNumberFromUser(message="input the line_weight(from 1 to 10)",
prompt="lineWeight", caption="drawer settings",
value=self.lineWeight,
parent=self.bmp, max=10, min=1)
print("SLW")
pass
去掉opencv自带的窗口,把图片绑定到wxPython框架上来
我感觉这部分是最复杂的,需要两个实例,image = cv2.imread()和bitmap = wx.bitmap(),从而搭起一个从opencv到wxPython的桥梁
这里最核心的代码是
def setImage(self,img):
self.image = img
img_height, img_width = img.shape[:2]
try:
image1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
except:
image1 = cv2.cvtColor(img,cv2.COLOR_GRAY2RGB)
finally:
pic = wx.Bitmap.FromBuffer(img_width, img_height, image1)
# 显示图片在panel上
self.bmp.SetBitmap(pic)
关于代码
设计代码的初衷
在实验室接触到了opencv这个库,感觉太强大了,于是想自己做一款功能比较全面的图片编辑软件,但是一个人的力量有限,我写了一个晚上,只写好了框架和图片裁剪
、图片黑白化
、图片涂鸦
这几个功能,希望以后有小伙伴一起参与进来
暂时不考虑开源,不过可以下载exe程序体验
代码更新优化
关于修复闪屏的问题(2018/12/11)
发现使用matplotlib绑定到wxPython上再使用canvas绘图,比用cv2画图再转成bitmap强制刷新到wxPython上要好得多,后者容易闪屏,期末以后再优化。