閱讀493 返回首頁    go 阿裏雲 go 技術社區[雲棲]


[Qt Topic] – 二維繪圖研習,做一個簡單批量水印工具

[Qt Topic] – 二維繪圖研習,做一個簡單批量水印工具

作者:Jason Lee

日期:2010-05-02

平台:Qt SDK v2010.02.1 + Windows Xp

聲明:文章作者僅在Intel軟件網絡CSDN博客發表本文,如有轉載,請注明出處

 

[1]二維繪圖概覽

Qt中的二維繪圖是基於QPainterQPaintEngineQPaintDevice機製的:以QPaintEngine作為中間接口,使用QPainter在不同繪圖設備上進行繪圖操作,而QPaintDevice就是可使用QPainter進行繪圖的二維空間。

使用QPainter可以在繪圖設備上進行繪製以下類的實例:QImageQBitmapQIconQPixmapQPicture等各種圖像和QPointQLineQPolygon等各種圖形以及其它許多,難以列舉。

目前QPaintDevice的子類有QWidgetQGLWidgetQImageQPixmapQGLPixelBufferQGLFrameBufferObjectQPictureQPrinter。也就是說,可以使用QPainter對這些類的實例進行繪圖操作。

 

[2]批量水印工具簡單設想

第一,既然是批量處理,那麼第一個要求是能夠打開多個文件。在這裏,我將之處理為打開一個文件夾下麵所有可支持的圖片,但並未繼續遞歸深入地讀取子文件夾。

第二,要有水印功能,就要求工具能夠對打開的圖片進行繪圖操作。這一點比較簡單,就是以上提到的使用QPainter在繪圖設備上(比如QImage)進行繪圖操作。針對這項功能,我隻是簡單地提供一個行文本框以輸入要水印的文字。

第三,因為隻是一個簡單的、練手的小工具,所以我真的十分簡單地實現了它的界麵、功能。

第四,可以稍微討論的擴展有:不隻是可以用文本進行水印,也可以用圖片,原理基本一致;可以繼續遞歸地打開子文件夾中的圖像;可以對QListWidget中的項進行右鍵處理,比如從列表中移除;其它……

 

[3]簡單水印工具的實現

首先是布局代碼。我簡單地將界麵分為3列:第一列用來打開目標文件夾,進而對裏麵的圖片進行處理;第二列是圖片列表,可以切換著觀察圖片;第三列就是圖片瀏覽區域。以下是部分代碼:

QLabel *markLabel; QLineEdit *markText; QHBoxLayout *markLayout; QLabel *folderLabel; QLineEdit *folderEdit; QPushButton *openFolderBtn; QHBoxLayout *folderLayout; QPushButton *applyBtn; QVBoxLayout *leftLayout; QListWidget *filesList; QLabel *imageLabel; QScrollArea *scrollArea; QHBoxLayout *mainLayout;   

接著是打開目標文件夾,

connect(openFolderBtn, SIGNAL(clicked()), this, SLOT(slotOpenFolder())); dirPath = QFileDialog::getExistingDirectory(this, tr("Please Select a Directory"), "", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); folderEdit->setText(dirPath); QDir dir(dirPath);

然後讀取該目錄下所有可支持的圖片:

QStringList filters; foreach (QByteArray format, QImageReader::supportedImageFormats()) filters += "*." + format; foreach (QString file, dir.entryList(filters, QDir::Files)){ files.append(file); filesList->addItem(file); }

並且瀏覽第一張圖片:

if(!files.isEmpty()){ QImage image(dirPath + '/' + files.at(0)); imageLabel->setPixmap(QPixmap::fromImage(image)); imageLabel->adjustSize(); }

到這裏,我們實現了打開目標文件夾並將目錄下所有圖像文件添加進來的功能。

 

為了實現點擊不同的圖片Item能達到切換圖片進行觀看的功能,首先連接信號和槽:

connect(filesList, SIGNAL(currentRowChanged(int)), this, SLOT(slotChangeImage(int)));

通過QListWidget當前Item的切換信號連接到切換圖像的槽,具體代碼如下:

void Topic::slotChangeImage(int i){ if(-1 == i) return; if(!files.isEmpty()){ QImage image(dirPath + '/' + files.at(i)); imageLabel->setPixmap(QPixmap::fromImage(image)); imageLabel->adjustSize(); } }

這就達到了切換瀏覽圖片的目的了。

 

最後就是對所有圖片進行水印處理了。

首先,要確保有用來水印的文字,markText就是此用途:

  if(markText->text() == ""){ QMessageBox::warning(this, tr("Warning"), tr("No text for marking")); return; }

在有水印文本的條件下,使用QPainter對象來對QImage這個QPaintDevice的子類的實例進行繪圖,本質就是簡單地使用一下drawText成員函數:

for(int i=0; i<files.size(); ++i){ QImage image(dirPath + '/' + files.at(i)); QPainter painter(&image); painter.setRenderHint(QPainter::Antialiasing, true); painter.setPen(QPen(Qt::blue, 20, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter.drawText(10, 10, markText->text()); image.save(dirPath + '/' + files.at(i)); } imageLabel->setPixmap(QPixmap::fromImage(QImage(dirPath + '/' + files.at(0)))); imageLabel->adjustSize();

在上麵代碼中,每次處理完一張圖片都立即保存,而如果需要的話可以稍微改動下僅僅實現預覽功能,待用戶確認後再進行應用以及保存。

水印後的效果圖如下:

由於本次的代碼挺簡單的,就不特地做上傳了。

各位晚安!

最後更新:2017-04-02 05:21:05

  上一篇:go magento 1.4-- 1.3時代常用插件兼容性測試
  下一篇:go C# Socket編程