python,一个入门级极简单的图像处理工具(二)

先来看本地图片的打开,因为本人新手入坑,是在遇到太多奇奇怪怪的问题,总结之后主要问题:1. tkinter与pillow的图片对象问题 2. 图片过大压缩问题

1. 对象问题:

Tkinter 以及pillow都可以打开图片,tkinter展示,pillow处理以及保存,且tkinter对象转pillow对象更加方便。所以采用tkinter获取本地地址,传值给picure类获取选定图片,传回Win类显示的方法,并在保存时将打开的tkinter图片对象转化为pillow对象保存。

Win类:

# 打开图片时使用,传值(图)给展示函数
    def openToshow(self):
        address = self.getAddress()
        self.open_picToimg = self.picture.open_pic(address)
        self.firstPic(self.open_picToimg)
        self.show_img(self.open_picToimg)
        
# 打开图片时使用,获得地址
    def getAddress(self):
        path = tk.StringVar()
        file_entry = tk.Entry(self, state='readonly', text=path)
        path_ = askopenfilename()
        path.set(path_)
        self.picture = picture()
        return file_entry.get()

# 展示函数
    def show_img(self, n_img):
        self.img = n_img  # self.img PIL对象方便传值给picture类以及本类中其他需要使用PIL图像的地方
        img_show = ImageTk.PhotoImage(self.img)
        self.image_l.config(image=img_show)
        self.image_l.image = img_show
        return self.img

# 保存函数
    def save_pic(self):
        fname = tkinter.filedialog.asksaveasfilename(title='保存文件', filetypes=[("PNG", ".png")])
        self.img.save(str(fname))  # PIL保存

pictire类:

# 打开图像调用
    def open_pic(self, address):
        self.pic_get = Im.open(address).convert('RGBA')
        wid, hei = self.pic_get.size
        if wid > 600 or hei > 400:
            if tk.messagebox.askokcancel('提示', '图片可能过大,是否压缩?'):
                needShow_pic = self.openResize()
                return needShow_pic
            return self.pic_get
        else:
            return self.pic_get

展示:

# 展示函数
    def show_img(self, n_img):
        self.img = n_img  # self.img PIL对象方便传值给picture类以及本类中其他需要使用PIL图像的地方
        img_show = ImageTk.PhotoImage(self.img)
        self.image_l.config(image=img_show)
        self.image_l.image = img_show
        return self.img

考虑之后的图片重置,这里需要Win类存有最开始的图片:

# 原图储存
    def firstPic(self, pic):
        self.Fpic = pic
        return self.Fpic

2. 压缩问题:

窗体大小设置为1080720,且展示区域只有720720,图片过大一定会展示不全,此时考虑压缩。(之后的图片尺寸大小方法一样,只是多一步获取用户输入值。)pillow压缩。
在pillow获取图片是查看图片属性判断是否过大,过大也询问压缩(上图有),调用压缩,将值固定在500*300:

# 打开图像时的图像压缩展示
    def openResize(self):
        w, h = self.pic_get.size
        w_hope = 500
        h_hope = 300
        f1 = 1.0 * w_hope / w
        f2 = 1.0 * h_hope / h
        factor = min([f1, f2])
        width = int(w * factor)
        height = int(h * factor)
        pic_show = self.pic_get.resize((width, height))
        return pic_show

图片的打开与保存完成:
在这里插入图片描述
在这里插入图片描述

接下来的截图以及尺寸改变没啥好多说的,截图因为opencv的响应速度实在太慢,最终没有使用opencv支持鼠标绑定,也没有做鼠标截图,这个是个硬伤,之后应该会重写。尺寸改变上面说了。。。直接代码:

操作窗口界面:

 # 截图操作页面
    def window_cut(self):
        Cut_win = tk.Toplevel()
        Cut_win.title('截图操作')
        Cut_win.geometry('220x380')
        nowPic = self.img
        if self.img == None:
            lNone = tk.Label(Cut_win, text='请先打开一张图片')
            lNone.place(y=55, x=50)
        else:
            wNow, hNow = nowPic.size
            l1 = tk.Label(Cut_win, text="此时图片尺寸:")
            l1.place(y=30, x=25)
            l2 = tk.Label(Cut_win, text=wNow)
            l2.place(y=55, x=25)
            l3 = tk.Label(Cut_win, text="X")
            l3.place(y=55, x=65)
            l4 = tk.Label(Cut_win, text=hNow)
            l4.place(y=55, x=85)
            l5 = tk.Label(Cut_win, text="截图区域")
            l5.place(y=85, x=25)
            l6 = tk.Label(Cut_win, text="起始点:(左上为(0,0))")
            l6.place(y=115, x=25)
            l7 = tk.Label(Cut_win, text="x:")
            l7.place(y=145, x=25)
            self.e1 = tk.Entry(Cut_win, width=10)
            self.e1.place(y=145, x=55)
            l8 = tk.Label(Cut_win, text="y:")
            l8.place(y=180, x=25)
            self.e2 = tk.Entry(Cut_win, width=10)
            self.e2.place(y=180, x=55)
            l9 = tk.Label(Cut_win, text="终止点:")
            l9.place(y=220, x=25)
            l10 = tk.Label(Cut_win, text="x:")
            l10.place(y=250, x=25)
            self.e3 = tk.Entry(Cut_win, width=10)
            self.e3.place(y=250, x=55)
            l11 = tk.Label(Cut_win, text="y:")
            l11.place(y=285, x=25)
            self.e4 = tk.Entry(Cut_win, width=10)
            self.e4.place(y=285, x=55)
            b1 = tk.Button(Cut_win, text='确定', command=self.getCutpart)
            b1.place(y=320, x=80, width=40)
            b2 = tk.Button(Cut_win, text='完成', command=Cut_win.destroy)
            b2.place(y=350, x=150, width=40)

 # 大小尺寸操作窗口
    def window_size(self):
        Size_win = tk.Toplevel()
        Size_win.title('尺寸操作')
        Size_win.geometry('200x180')
        l1 = tk.Label(Size_win, text="宽:")
        l1.place(y=30, x=25)
        self.text1 = tk.Entry(Size_win, width=10)
        self.text1.place(y=25, x=50)
        l1_1 = tk.Label(Size_win, text="px")
        l1_1.place(y=28, x=150)
        l2 = tk.Label(Size_win, text="高:")
        l2.place(y=60, x=25)
        self.text2 = tk.Entry(Size_win, width=10)
        self.text2.place(y=55, x=50)
        l2_1 = tk.Label(Size_win, text="px")
        l2_1.place(y=58, x=150)
        b1 = tk.Button(Size_win, text='确定', command=self.getSize_change)
        b1.place(y=100, x=80, width=40)
        b2 = tk.Button(Size_win, text='完成', command=Size_win.destroy)
        b2.place(y=145, x=140, width=40)

Win类:

 # 接收截图区域,传送展示
    def getCutpart(self):
        nCut_pic = self.img
        x = int(self.e1.get())
        y = int(self.e2.get())
        xl = int(self.e3.get())
        yl = int(self.e4.get())
        self.picture = picture()
        showCut_pic = self.picture.Cutpic(nCut_pic, x, y, xl, yl)
        self.show_img(showCut_pic)

# 获得输入尺寸
    def getSize_change(self):
        sizeNum_w = int(self.text1.get())
        sizeNum_h = int(self.text2.get())
        # print('1')
        self.showSize_change(sizeNum_w, sizeNum_h)
        # print(sizeNum_w, sizeNum_h)

# 尺寸修改并展示图片
    def showSize_change(self, renewSize_w, renewSize_h):
        # print('2')
        self.picture = picture()
        needResize_pic = self.img
        show_resizePic = self.picture.changeResize(needResize_pic, renewSize_w, renewSize_h)
        self.show_img(show_resizePic)

picture类:

# 截图处理
    def Cutpic(self, pic_preCut, p1, p2, p3, p4):
        cropped_pic = pic_preCut.crop((p1, p2, p3, p4))
        return cropped_pic

# 尺寸大小变化
    def changeResize(self, pic_reshow, newWidth, newHeight):
        reesizeNew_pic = pic_reshow.resize((newWidth, newHeight))
        # print('3')
        return reesizeNew_pic
文字添加也是如此,无法绑定鼠标,功能鸡肋,,,,镜像很简单:

Win类;

# 文字添加功能窗口
    def window_word(self):
        Word_win = tk.Toplevel()
        Word_win.title('镜像操作')
        Word_win.geometry('200x250')
        l1 = tk.Label(Word_win, text='请输入文字:')
        l1.place(y=20, x=25, width=80)
        self.textWord = tk.Entry(Word_win, width=17)
        self.textWord.place(y=45, x=15)
        l2 = tk.Label(Word_win, text='请选择文字颜色:')
        l2.place(y=85, x=25, width=105)
        b1 = tk.Button(Word_win, text='红色', width=8, command=lambda: self.getWord_input('red'))
        b1.place(y=120, x=20)
        b2 = tk.Button(Word_win, text='黑色', width=8, command=lambda: self.getWord_input('black'))
        b2.place(y=120, x=100)
        b3 = tk.Button(Word_win, text='蓝色', width=8, command=lambda: self.getWord_input('blue'))
        b3.place(y=150, x=20)
        b4 = tk.Button(Word_win, text='绿色', width=8, command=lambda: self.getWord_input('green'))
        b4.place(y=150, x=100)
        b5 = tk.Button(Word_win, text='黄色', width=8, command=lambda: self.getWord_input('yellow'))
        b5.place(y=180, x=20)
        b6 = tk.Button(Word_win, text='白色', width=8, command=lambda: self.getWord_input('white'))
        b6.place(y=180, x=100)
        b7 = tk.Button(Word_win, text='完成', command=Word_win.destroy)
        b7.place(y=220, x=150)

# 获得文字添加的相关对象
    def getWord_input(self, color):
        self.picture = picture()
        needWord_pic = self.img
        showWord = self.textWord.get()
        # print(showWord)
        # print(color)
        showInword_pic = self.picture.wordInput(needWord_pic, showWord, color)
        self.show_img(showInword_pic)

# 镜像操作窗口
    def window_mirror(self):
        Mir_win = tk.Toplevel()
        Mir_win.title('镜像操作')
        Mir_win.geometry('150x150')
        b1 = tk.Button(Mir_win, text='左右', command=self.MirrorImg_lr)
        b1.place(y=30, x=35, width=75)
        b2 = tk.Button(Mir_win, text='上下', command=self.MirrorImg_tb)
        b2.place(y=60, x=35, width=75)
        b3 = tk.Button(Mir_win, text='完成', command=Mir_win.destroy)
        b3.place(y=110, x=80, width=40)

# 镜像左右调用展示
    def MirrorImg_lr(self):
        self.picture = picture()
        Mirror_img_lr = self.img
        MittotImg_lrFinish = self.picture.MirrorPic_leftOrright(Mirror_img_lr)
        self.show_img(MittotImg_lrFinish)

# 镜像上下调用展示
    def MirrorImg_tb(self):
        self.picture = picture()
        Mirror_img_tb = self.img
        MittotImg_tbFinish = self.picture.MirrorPic_topOrbuttom(Mirror_img_tb)
        self.show_img(MittotImg_tbFinish)

picture类:

# 文字添加
    def wordInput(self, pic_preWord, textEn, fillColor):
        Wordpic_width, Wordpic_height = pic_preWord.size
        wordFont = ImageFont.truetype('./use.TTF', 30)
        draw = ImageDraw.Draw(pic_preWord)
        draw.text((20, Wordpic_height - 35), text=textEn, font=wordFont, fill=fillColor)
        return pic_preWord

# 镜像左右
    def MirrorPic_leftOrright(self, pic_mir_lr):
        Mirror_lrFinish = pic_mir_lr.transpose(Im.FLIP_LEFT_RIGHT)
        return Mirror_lrFinish

# 镜像上下
    def MirrorPic_topOrbuttom(self, pic_mir_tp):
        Mirror_tbFinish = pic_mir_tp.transpose(Im.FLIP_TOP_BOTTOM)
        return Mirror_tbFinish
发布了4 篇原创文章 · 获赞 2 · 访问量 911
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览