前段时间写了一个比较简单的批量加水印的python实现,给某个文件夹下的所有图片加水印。【阅读全文】今天有空就做了一个UI应用程序包,让我不需要懂python直接下载exe应用程序就可以使用了。需要'BatchImageWatermarkAdder'的朋友可以直接跳到文末获取下载方法,下载.exe可执行程序直接使用即可。下面主要介绍实现过程。首先,引入开发过程中需要用到的python非标准库还是老规矩,因为这些库以前都用过。所以这里直接导入到代码块中,如果没有可以直接pip安装。#它将PyQt5.QtCore模块的所有类、属性和方法导入到全局符号表中。fromPyQt5.QtCoreimport*#将PyQt5.QtWidgets模块的所有类、属性、方法导入到全局符号表中。,QFileDialog,QLabel#将PyQt5.QtGui模块的所有类、属性、方法导入全局。fromPyQt5.QtGuiimportQIcon,QFont,QTextCursor#导入sys模块。importsys#导入os模块。importos#导入loguru模块的logger。fromloguruimportlogger#导入add_mark函数watermarker包中的marker模块。fromwatermarker.markerimportadd_mark上面导入的python库是整个UI桌面应用开发过程中需要用到的,我们直接新建一个UI类PicWaterUI来写一些关于桌面应用的布局。它包括按钮和输入框等组件。另外,与组件关联的槽函数也写在这个类中,有利于统一管理。代码较多,需要耐心阅读的朋友。#此类是一个小部件,包含一个QLabel和一个QPushButton类PicWaterUI(QWidget):def__init__(self):"""构造函数。当从类创建对象时调用它,它允许类初始化一个类的属性。"""super(PicWaterUI,self).__init__()self.init_ui()definit_ui(self):"""该函数初始化UI。"""self.setWindowTitle('批量图片水印加法器:Python集中营!')self.setWindowIcon(QIcon('water.ico'))self.brower=QTextBrowser()self.brower.setFont(QFont('宋体',8))self.brower.setReadOnly(True)self.brower.setPlaceholderText('处理显示区域...')self.brower.ensureCursorVisible()self.pic_file_path=QLineEdit()self.pic_file_path.setPlaceholderText('源批处理图片路径')self.pic_file_path.setReadOnly(真)self.pic_file_path_btn=QPushButton()self.pic_file_path_btn.setText('源图片路径')self.pic_file_path_btn.clicked.connect(self.pic_file_path_btn_click)self.new_pic_file_path=QLineEdit()self.new_pic_file_path.setPlaceholder新图片存放路径'.new_pic_file_path.setReadOnly(True)self.new_pic_file_path_btn=QPushButton()self.new_pic_file_path_btn.setText('保存路径')self.new_pic_file_path_btn.clicked.connect(self.new_pic_file_path_btn_click)self.water_current_label=QLabel()self.water_current_label.setText('水印内容:')self.water_current_in=QLineEdit()self.water_current_in.setPlaceholderText('Python集中营')self.water_angle_label=QLabel()self.water_angle_label.setText('水印角度:')self.water_angle_in=QLineEdit()self.water_angle_in.setPlaceholderText('30')self.water_back_label=QLabel()self.water_back_label.setText('水印透明度:')self.water_back_in=QLineEdit()self.water_back_in.setPlaceholderText('0.3')self.water_font_label=QLabel()self.water_font_label.setText('水印字体大小:')self.water_font_in=QLineEdit()self.water_font_in.setPlaceholderText('30')self.water_space_label=QLabel()self.water_space_label.setText('水印间隔:')self.water_space_in=QLineEdit()self.water_space_in.setPlaceholderText('40')self.water_color_label=QLabel()self.water_color_label.setText('水印颜色:')self.water_color_in=QLineEdit()self.water_color_in.setPlaceholderText('#8B8B1B')self.start_btn=QPushButton()self.start_btn.setText('开始添加水印')self.start_btn.clicked.connect(self.start_btn_click)hbox=QHBoxLayout()hbox.addWidget(self.brower)fbox=QFormLayout()fbox.addRow(self.pic_file_path,self.pic_file_path_btn)fbox.addRow(self.new_pic_file_path,self.new_pic_file_path_btn)fbox.addRow(self.water_current_label,self.water_current_in)fbox.addRow(self.water_angle_label,self.water_angle_in)fbox.addRow(self.water_back_label,self.water_back_in)fbox.addRow(self.water_font_label,self.water_font_in)fbox.addRow(self.water_space_label,self.water_space_in)fbox.addRow(self.water_color_label,self.water_color_in)v_vbox=QVBoxLayout()v_vbox.addWidget(self.start_btn)vbox=QVBoxLayout()vbox.addLayout(fbox)vbox.addLayout(v_vbox)hbox.addLayout(vbox)self.thread_=PicWaterThread(self)self.thread_.message.connect(self.show_message)self.thread_.finished.connect(self.finshed)self.setLayout(hbox)defshow_message(self,text):"""显示一条消息:paramtext:要显示的文本"""cursor=self.brower.textCursor()cursor.movePosition(QTextCursor.End)self.brower.append(text)self.brower.setTextCursor(cursor)self.brower.ensureCursorVisible()defpic_file_path_btn_click(self):"""打开文件对话框框并允许用户选择文件。"""pic_file_path=QFileDialog.getExistingDirectory(self,'选择文件夹',os.getcwd())self.pic_file_path.setText(pic_file_path)defnew_pic_file_path_btn_click(self):"""这个函数打开一个文件对话框,允许用户选择一个文件来保存输出。"""new_pic_file_path=QFileDialog.getExistingDirectory(self,'选择文件夹',os.getcwd())self.new_pic_file_path.setText(new_pic_file_path)defstart_btn_click(self):"""单击开始按钮时调用的函数。""&qu哦;self.thread_.start()self.start_btn.setEnabled(False)deffinished(self,finished):""":paramfinished:一个布尔值,如果下载完成则为True,否则为False"""如果完成True:self.start_btn.setEnabled(True)页面布局和组件部分完成后,就是业务的具体实现部分。业务是实现批量添加水印的效果。这里,创建了一个新的PicWaterThread类作为UI桌面应用程序的子线程。业务实现部分写在这个类中。当业务部分直接与主线程分离时,一是从代码层面看起来清晰,二是子线程执行业务慢时,不会造成主线程卡死。为了达到业务和接口分离的效果,具体的业务实现部分在下面PicWaterThread子线程的run函数中。#该类是QThread的子类,用于给图片加水印classPicWaterThread(QThread):#收到消息时发出的信号。message=pyqtSignal(str)#下载完成时发出的信号。finished=pyqtSignal(bool)def__init__(self,parent=None):"""初始化类的构造函数。:paramparent:父部件"""super(PicWaterThread,self).__init__(parent)self.working=Trueself.parent=parentdef__del__(self):"""一个析构函数。当对象被销毁时调用它。"""self.working=Trueself.wait()defrun(self)->None:""">这个函数运行程序"""try:directory=self.parent.pic_file_path.text().strip()water_name=self.parent.water_current_in.text().strip()new_directory=self.parent.new_pic_file_path.text().strip()water_angle_in=self.parent.water_angle_in.text().strip()water_back_in=self.parent.water_back_in.text().strip()water_font_in=self.parent.water_font_in.text().strip()water_space_in=self.parent.water_space_in.text().strip()color=self.parent.water_color_in.text(.strip()self.message.emit('源文件路径:{}'.format(目录))self.message.emit('水印内容:{}'.format(water_name))self.message.emit('保存文件路径:{}'.format(new_directory))self.message.emit('水印角度:{}'.format(water_angle_in))self.message.emit('水印透明度:{}'.format(water_back_in))self.message.emit('水印字体大小:{}'.format(water_font_in))self.message.emit('水印间隔:{}'.format(water_space_in))self.message.emit('水印颜色:{}'.format(颜色))ifdirectoryisNoneorwater_nameisNone:logger.info('文件夹地址或水印名称不能为空!')returnforfile_nameinos.listdir(directory):logger.info('当前文件名:{0},即将开始添加水印!'.format(file_name))self.message.emit('当前文件名:{0},即将开始添加水印!'.format(file_name))add_mark(file=os.path.join(directory,file_name),out=new_directory,mark=water_name,opacity=float(water_back_in),angle=int(water_angle_in),space=int(water_space_in),size=int(water_font_in),color=color)自我.信息。emit('当前文件名:{0},加水印完成!'.format(file_name))logger.info('当前文件名:{0},加水印完成!'.format(file_name))self.finished.emit(True)exceptExceptionase:self.message.emit('读取或格式化文件内容时发生异常!')self.finished.emit(True)开发完成后业务和页面应用,我们使用main函数调出整个桌面应用。这种范例对于每个桌面应用程序来说基本上是相同的。如果你需要更好看,还可以添加我们之前提到的各种风格和主题的应用。在公众号主页搜索之前发表的相关文章。if__name__=='__main__':app=QApplication(sys.argv)main=PicWaterUI()main.show()sys.exit(app.exec_())最后我们找到了两张斗罗大陆‘唐三’测试的照片它是如何工作的,使用上面的main函数启动整个应用程序后的样子。您可以在应用程序上直接选择需要批量添加水印的图片的路径和添加完成后的保存位置。并且您可以在生成时在桌面应用中调整与水印相关的各种参数,包括水印的大小、大小、间隔、颜色等,方便您根据自己的需要制作批量图片的水印效果。下面是通过这个页面转换《唐三》照片的效果,基本满足我对大量图片加同水印的要求。接下来,让我们看看《修罗唐三》在我们加上了《蟒蛇集中营》的水印之后变成了什么样子。需要.exe可执行应用程序的朋友可以直接在公众号回复'BatchImageWatermarkAdder'获取网盘下载链接。我们已经打包好应用,需要的可以直接下载。这个以后用于字符串中的字符提取和校验,效果不错!方便数据分析,实现Python对象与DataFrame数据的相互转换!Python数据分析透视表,定制你的分析计算需求!
