图片水印是在数字图片上叠加一些隐蔽或透明的标识,以证实其版权、来源或其他信息的技术。水印可以是文字、图案、Logo等,用于保护图片的版权并防止未经授权的复制和使用。
步骤1: 安装必要的库
首先,确保你的环境中安装了Python和PyQT。然后,安装必要的库:
pip install PyQT5 pillow
步骤2: 创建PyQT应用程序框架
我们将创建一个基本的PyQT应用程序框架,包括主窗口和布局。
python
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("图片水印工具")
self.setGeometry(100, 100, 800, 600)
# 创建中心部件
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
# 创建布局
layout = QVBoxLayout()
central_widget.setLayout(layout)
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
步骤3: 添加控件
接下来,我们将添加控件,如按钮、文本框和图片显示区域。
python
from PyQt5.QtWidgets import QPushButton, QLabel, QLineEdit
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# ... 省略之前的代码 ...
# 添加控件
self.image_label = QLabel(self)
layout.addWidget(self.image_label)
self.watermark_text = QLineEdit(self)
self.watermark_text.setPlaceholderText("输入水印文本")
layout.addWidget(self.watermark_text)
self.load_button = QPushButton("加载图片", self)
layout.addWidget(self.load_button)
self.add_watermark_button = QPushButton("添加水印", self)
layout.addWidget(self.add_watermark_button)
self.save_button = QPushButton("保存图片", self)
layout.addWidget(self.save_button)
# 连接信号与槽
self.load_button.clicked.connect(self.load_image)
self.add_watermark_button.clicked.connect(self.add_watermark)
self.save_button.clicked.connect(self.save_image)
def load_image(self):
# 实现图片加载功能
pass
def add_watermark(self):
# 实现添加水印功能
pass
def save_image(self):
# 实现保存图片功能
pass
步骤4: 实现功能
现在,我们将实现加载图片、添加水印和保存图片的功能。
python
from PIL import Image, ImageDraw, ImageFont
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# ... 省略之前的代码 ...
def load_image(self):
options = QFileDialog.Options()
file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
if file_name:
self.image = Image.open(file_name)
# 将 Pillow 图像转换为 QImage
qimage = QImage(self.image.tobytes(), self.image.width, self.image.height, QImage.Format_RGB888)
# 将 QImage 转换为 QPixmap
self.image_label.setPixmap(QPixmap.fromImage(qimage))
def add_watermark(self):
if not hasattr(self, 'image'):
return
draw = ImageDraw.Draw(self.image)
font = ImageFont.truetype("arial.ttf", 36)
draw.text((10, 10), self.watermark_text.text(), font=font, fill=(255, 255, 255, 128))
self.image_label.setPixmap(QPixmap.fromImage(QImage(self.image.tobytes(), self.image.width, self.image.height, QImage.Format_RGB888)))
def save_image(self):
if not hasattr(self, 'image'):
return
options = QFileDialog.Options()
file_name, _ = QFileDialog.getSaveFileName(self, "保存图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
if file_name:
self.image.save(file_name)
完整代码
将上述所有代码整合到一个文件中,你将得到一个完整的图片增加水印工具。
python
import sys
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton, QLabel, QLineEdit, QFileDialog
from PIL import Image, ImageDraw, ImageFont
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("图片水印工具")
self.setGeometry(100, 100, 800, 600)
central_widget = QWidget(self)
self.setCentralWidget(central_widget)
layout = QVBoxLayout()
central_widget.setLayout(layout)
self.image_label = QLabel(self)
layout.addWidget(self.image_label)
self.watermark_text = QLineEdit(self)
self.watermark_text.setPlaceholderText("输入水印文本")
layout.addWidget(self.watermark_text)
self.load_button = QPushButton("加载图片", self)
layout.addWidget(self.load_button)
self.add_watermark_button = QPushButton("添加水印", self)
layout.addWidget(self.add_watermark_button)
self.save_button = QPushButton("保存图片", self)
layout.addWidget(self.save_button)
self.load_button.clicked.connect(self.load_image)
self.add_watermark_button.clicked.connect(self.add_watermark)
self.save_button.clicked.connect(self.save_image)
self.show()
def load_image(self):
options = QFileDialog.Options()
file_name, _ = QFileDialog.getOpenFileName(self, "选择图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
if file_name:
self.image = Image.open(file_name)
# 将 Pillow 图像转换为 QImage
qimage = QImage(self.image.tobytes(), self.image.width, self.image.height, QImage.Format_RGB888)
# 将 QImage 转换为 QPixmap
self.image_label.setPixmap(QPixmap.fromImage(qimage))
def add_watermark(self):
if not hasattr(self, 'image'):
return
draw = ImageDraw.Draw(self.image)
font = ImageFont.truetype("arial.ttf", 36)
draw.text((10, 10), self.watermark_text.text(), font=font, fill=(255, 255, 255, 128))
self.image_label.setPixmap(QPixmap.fromImage(QImage(self.image.tobytes(), self.image.width, self.image.height, QImage.Format_RGB888)))
def save_image(self):
if not hasattr(self, 'image'):
return
options = QFileDialog.Options()
file_name, _ = QFileDialog.getSaveFileName(self, "保存图片", "", "Images (*.png *.jpg *.jpeg)", options=options)
if file_name:
self.image.save(file_name)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec_())
实现效果如下:
总结
本文介绍了一个简易版的图片加水印小工具的开发示例,大致思路如下:
-
导入必要的模块和库:导入了sys、QPixmap、QImage、QApplication、QMainWindow、QWidget、QVBoxLayout、QPushButton、QLabel、QLineEdit和QFileDialog等模块,以及Pillow库中的Image、ImageDraw和ImageFont模块。
-
创建主窗口类MainWindow:定义了一个继承自QMainWindow的类MainWindow,用于显示程序的主窗口界面和处理用户交互。
-
初始化界面:在MainWindow类的初始化方法__init__中,设置了窗口标题、大小,并创建了主窗口的布局和控件,包括一个用于显示图片的标签、一个输入水印文本的文本框、加载图片的按钮、添加水印的按钮和保存图片的按钮。
-
绑定按钮点击事件:通过clicked.connect()方法,将加载图片按钮、添加水印按钮和保存图片按钮与对应的处理方法load_image、add_watermark和save_image绑定在一起。
-
加载图片:当用户点击加载图片按钮时,使用QFileDialog打开文件对话框选择图片文件,并将选择的图片文件用Pillow库中的Image打开,然后将其转换为QImage格式,并显示在程序界面的图片标签上。
-
添加水印:当用户点击添加水印按钮时,首先判断是否已经加载了图片,然后使用Pillow库中的ImageDraw和ImageFont来给图片添加指定的文本水印,并更新显示在界面上的图片标签。
-
保存图片:当用户点击保存图片按钮时,首先判断是否已经加载了图片,然后使用QFileDialog打开文件对话框选择保存路径,并将图片保存到指定的路径。
-
启动应用程序:在主程序中创建了QApplication实例app,并实例化了MainWindow类的对象window,并通过sys.exit(app.exec_())启动了应用程序的事件循环。
程序的功能还比较简陋,仅供练手参考,后续针对这个程序还可以有更多的优化空间,比如:
-
错误处理:在加载图片、添加水印和保存图片的过程中,可以添加一些错误处理,例如捕获文件操作可能出现的异常,并向用户提供友好的错误提示。
-
图片显示优化:对于较大的图片,可以在加载时进行适当的缩放处理,以提高程序的响应速度和用户体验。
-
界面优化:可以考虑对界面进行美化,增加一些图标、布局调整或者添加状态栏等元素,以提高用户交互体验。
-
水印位置和样式:目前的代码中水印的位置固定在(10, 10)处,可以考虑添加更多选项来让用户自定义水印的位置、大小、颜色等样式。
-
支持更多图片格式:目前只支持png、jpg和jpeg格式的图片,可以考虑扩展支持更多常见的图片格式。
-
多语言支持:可以考虑添加多语言支持,让用户可以选择不同的界面语言,等等。