制作证件照排版软件

来源:互联网 发布:linux more 向前翻页 编辑:程序博客网 时间:2024/04/29 19:25

制作证件照排版软件

媳妇开了个摄影店,经常要拍证件照,证件照拍好后,需要在ps里面修饰一下,然后排成多张进行打印。
之前排版都是手工在ps里进行的。如下图所示,左侧是裁剪好的一寸证件照,右图是排好版准备打印的,排版照片
这里写图片描述
其中右侧9张照片排版是手工排版的,虽然简单,但也比较费时间,而且照片的间距是靠目测的,没有固定值。作为程序员,我感觉到可以用软件来做这个事情。

制作软件

说干就干,首先想到用熟悉的QT来做一个,在说怎么做之前,先看看最终效果
这里写图片描述
利用这个软件,只要拖入修饰裁剪好的单张照片,即可自动生成排版好的图片,间距都是固定的,非常整齐,并且可以直接点击打印按钮进行打印。
好了,开始看代码

图片浏览器

首先需要做一个图片浏览器,用于展示排版好的图片,我通过直接继承QWidget类,并重写paintEvent函数来绘制图片,头文件声明如下

// imageview.hclass ImageView : public QWidget{    Q_OBJECTpublic:    explicit ImageView(QWidget *parent = 0);    //重点函数:重载绘制事件用于绘制图片    void paintEvent( QPaintEvent * );    //设置要显示的图片    void setImage(const QImage &image);    void setImage(const QString &imageFile);    // 设置四周的空白区域,图片四周不顶满,留点空白会好看一些    // 不过现在看来四周边距设置一个值就行了,没必要设置4个值,当时考虑太多    void setBottomPadding(int padding);    void setTopPadding(int padding);    void setRightPadding(int padding);    void setLeftPadding(int padding);    //    void setBackgroundColor(QColor color);signals:public slots:private :    QImage currentImage;    int bottomPadding;    int topPadding;    int rightPadding;    int leftPadding;    QColor backgroundColor;};

下面看一下具体实现代码

ImageView::ImageView(QWidget *parent) :    QWidget(parent){    bottomPadding = 10;    topPadding = 10;    rightPadding = 10;    leftPadding = 10;    setBackgroundColor(Qt::black);}void ImageView::paintEvent( QPaintEvent *paintEvent ){    QPainter painter(this);    //先在widget上全部填上背景色    painter.fillRect(0,0,width(),height(),backgroundColor);    //如果没有设置图片,就直接退出,那么整个wdiget就会显示成背景色    if(currentImage.isNull()) {        return;    }    //实际可显示图片的区域,要除去四周留白    int actualWidth = width() - (rightPadding + leftPadding);    int actualHeight = height() - (topPadding + bottomPadding);    //将图片缩放到显示区域的大小,保持比例不变    QImage showImage =        currentImage.scaled(QSize(actualWidth,actualHeight),Qt::KeepAspectRatio);    //计算显示图片的左上角坐标,让图片居中显示    int x = leftPadding + (actualWidth - showImage.width()) / 2;    int y = topPadding  + (actualHeight - showImage.height()) / 2;    //绘制图片    painter.drawImage(x,y,showImage);}void ImageView::setImage(const QImage &image){    currentImage = image;    update();}

这个图片浏览器是非常简单的,最主要的问题就是不能缩放图片,只能以widget大小最大化显示图片,但在我们这个场景下面也足够用了。

功能介绍

首先看一下软件功能,在截个图,这里为了区分说明功能,将配置改的有点奇怪
这里写图片描述
软件的功能有三点
- 照片张数设置
在左上方的打开按钮边上,有张数设置,分别表示横向排几张,纵向排几张
- 边距和间隔设置
在界面右上方有边距和间隔设置,分别设置照片之间的间隔和照片四周的间距
- 打印功能
好了,介绍完毕,看一下主窗口的代码,总共200行左右

主窗口的构造函数

MainWindow::MainWindow(QWidget *parent) :    QMainWindow(parent),    ui(new Ui::MainWindow){    ui->setupUi(this);    //打开,保存,打印按钮的事件处理    connect(ui->openButton,SIGNAL(clicked()),this,SLOT(openFile()));    connect(ui->saveButton,SIGNAL(clicked()),this,SLOT(saveFile()));    connect(ui->printButton,SIGNAL(clicked()),this,SLOT(printImage()));    //边距,间隔,或者照片张数发生变化时候,都要重新生成并显示新的图片,达到实时更新的效果    connect(ui->marginBox,SIGNAL(valueChanged(int)),this,SLOT(updateImage()));    connect(ui->xcountBox,SIGNAL(valueChanged(int)),this,SLOT(updateImage()));    connect(ui->ycountBox,SIGNAL(valueChanged(int)),this,SLOT(updateImage()));    connect(ui->paddingBox,SIGNAL(valueChanged(int)),this,SLOT(updateImage()));    //从注册表中读取照片边距和间隔设置    //如果没有设置,则默认值是30    QSettings settings;    int padding = settings.value("padding",30).toInt();    int margin = settings.value("margin",30).toInt();    ui->marginBox->setValue(margin);    ui->paddingBox->setValue(padding);    //开启拖放功能    setAcceptDrops(true);}

对应构造函数的边距和间隔设置,需要在窗口关闭时保存这两个设置

void MainWindow::closeEvent(QCloseEvent *event){    QSettings settings;    settings.setValue("margin",ui->marginBox->value());    settings.setValue("padding",ui->paddingBox->value());}

拖放文件处理

拖放是简化软件操作的重要手段,在QT中通过重载dragEnterEvent和dropEvent两个函数实现

void MainWindow::dragEnterEvent(QDragEnterEvent *event){    if (event->mimeData()->hasFormat("text/uri-list"))            event->acceptProposedAction();}void MainWindow::dropEvent(QDropEvent *event){    QList<QUrl> urls = event->mimeData()->urls();    if(urls.isEmpty())        return;    QString fileName = urls.at(0).toLocalFile();    QImage image(fileName);    if(image.isNull()) {        return;    }    openImage(image);}

固定张数处理

对于最常见的1寸和2寸照片,照片张数是固定的,1寸是9张,2寸是4张
这里直接写死了,最好是做个可配置化,偷懒没有做

#define ONE_INCH 1 //1寸#define TWO_INCH 2 //2寸static int inch(const QSize size){    if(size == QSize(250,350)) {        return ONE_INCH;    }    if(size == QSize(350,500)){        return TWO_INCH;    }    return -1;}void MainWindow::openImage(QImage image){    if(image.isNull()) {        return;    }    int i = inch(image.size());    switch(i) {        case ONE_INCH:            ui->xcountBox->setValue(3);            ui->ycountBox->setValue(3);            break;        case TWO_INCH:            ui->xcountBox->setValue(2);            ui->ycountBox->setValue(2);            break;    }    currentImage = image;    updateImage();}

生成拼版图片

当有配置改变或者新图片打开时会调用updateImage函数
在这个函数中会根据当前配置生成新图片,并放到图片浏览器中显示

void MainWindow::updateImage(){    if(currentImage.isNull()) {        return;    }    int new_xcount = ui->xcountBox->value();    int new_ycount = ui->ycountBox->value();    int new_margin = ui->marginBox->value();    int new_padding = ui->paddingBox->value();    xcount = new_xcount == 0 ? 1 : new_xcount;    ycount = new_ycount == 0 ? 1 : new_ycount;    margin = new_margin;    padding = new_padding;    generateImage = createImage();    ui->imageView->setImage(generateImage);}QImage MainWindow::createImage(){    int width = xcount * currentImage.width() + margin * (xcount - 1) + padding * 2;    int height = ycount * currentImage.height() + margin * (ycount - 1) + padding *2;    QImage dstImage(width,height,currentImage.format());    QPainter painter(&dstImage);    dstImage.setDotsPerMeterX(10000);    dstImage.setDotsPerMeterY(10000);    painter.fillRect(0,0,dstImage.width(),dstImage.height(),Qt::white);    for(int w = 0; w < xcount; w++){        for(int h = 0; h < ycount; h ++) {            int x = padding + (margin + currentImage.width()) * w ;            int y = padding + (margin + currentImage.height()) * h;            painter.drawImage(x,y,currentImage);        }    }    return dstImage;}

打印功能

当点击打印按钮时会显示打印对话框,点击确定后,可以直接打印图片
这里写图片描述

void MainWindow::printImage(){    if(generateImage.isNull()) {        return;    }    QPrinter printer;    QPrintDialog printDialog(&printer,this);    if(printDialog.exec() != QDialog::Accepted) {        return;    }    //设置分辨率为254    printer.setResolution(254);    //设置纸张为A4    printer.setPageSize(QPrinter::A4);    QPainter painter(&printer);    painter.drawImage(0,0,generateImage);}

当打开图片或者更改设置后会调用updateImage函数,在这个函数里面处理一下张数,边距,间隔设置,
然后生成新的拼版图片并调用图片浏览器显示出来

以上就是全部主要代码,匆匆忙忙的介绍完啦,第一次写博客,希望对需要的人有帮助~~

0 0