#include "imagecropperdemo.h" #include #include #include #include #include #include ImageCropperDemo::ImageCropperDemo(QWidget* parent) : QDialog(parent) { setupLayout(); init(); this->setAttribute(Qt::WA_DeleteOnClose, true); this->setWindowTitle("图片裁剪工具"); } void ImageCropperDemo::setupLayout() { imgCropperLabel = new ImageCropperLabel(600, 500, this); imgCropperLabel->setFrameStyle(1); comboOutputShape = new QComboBox(this); comboCropperShape = new QComboBox(this); labelPreviewImage = new QLabel(this); editOriginalImagePath = new QLineEdit(this); btnChooseOriginalImagePath = new QPushButton(this); QHBoxLayout* hOriginalImagePathLayout = new QHBoxLayout(); hOriginalImagePathLayout->addWidget(editOriginalImagePath); hOriginalImagePathLayout->addWidget(btnChooseOriginalImagePath); //图片分辨率设置 editResolution = new QLineEdit("500",this); QHBoxLayout* hResolutionLayout = new QHBoxLayout(); hResolutionLayout->addWidget(editResolution); //裁剪尺寸,单位像素 editCropperFixedWidth = new QLineEdit(this); editCropperFixedHeight = new QLineEdit(this); QHBoxLayout* hCropperFixedSizeLayout = new QHBoxLayout(); hCropperFixedSizeLayout->addWidget(editCropperFixedWidth); hCropperFixedSizeLayout->addWidget(editCropperFixedHeight); editCropperMinWidth = new QLineEdit("8", this); editCropperMinHeight = new QLineEdit("8", this); QHBoxLayout* hCropperMinSizeLayout = new QHBoxLayout(); hCropperMinSizeLayout->addWidget(editCropperMinWidth); hCropperMinSizeLayout->addWidget(editCropperMinHeight); //裁剪尺寸,单位厘米 editFixedWidth = new QLineEdit(this); editFixedHeight = new QLineEdit(this); QHBoxLayout* hFixedSizeLayout = new QHBoxLayout(); hFixedSizeLayout->addWidget(editFixedWidth); hFixedSizeLayout->addWidget(editFixedHeight); checkEnableOpacity = new QCheckBox(this); sliderOpacity = new QSlider(Qt::Horizontal, this); checkShowDragSquare = new QCheckBox(this); editDragSquareEdge = new QLineEdit("8", this); checkShowRectBorder = new QCheckBox(this); labelRectBorderColor = new QLabel(this); btnChooseRectBorderCorlor = new QPushButton(this); QHBoxLayout* hRectBorderColorLayout = new QHBoxLayout(); hRectBorderColorLayout->addWidget(labelRectBorderColor); hRectBorderColorLayout->addWidget(btnChooseRectBorderCorlor); labelDragSquareColor = new QLabel(this); btnChooseDragSquareColor = new QPushButton(this); QHBoxLayout* hDragSquareColorLayout = new QHBoxLayout(); hDragSquareColorLayout->addWidget(labelDragSquareColor); hDragSquareColorLayout->addWidget(btnChooseDragSquareColor); QFormLayout* formLayout1 = new QFormLayout(); formLayout1->addRow(new QLabel("预览:"), labelPreviewImage); formLayout1->addRow(new QLabel("原图路径:", this), hOriginalImagePathLayout); formLayout1->addRow(new QLabel("输出形状:", this), comboOutputShape); formLayout1->addRow(new QLabel("裁剪形状:", this), comboCropperShape); formLayout1->addRow(new QLabel("分辨率:", this), hResolutionLayout); formLayout1->addRow(new QLabel("像素尺寸:", this), hCropperFixedSizeLayout); formLayout1->addRow(new QLabel("厘米尺寸:", this), hFixedSizeLayout); formLayout1->addRow(new QLabel("最小尺寸:", this), hCropperMinSizeLayout); QFormLayout* formLayout2 = new QFormLayout(); formLayout2->addRow(new QLabel("透明度:", this), checkEnableOpacity); formLayout2->addRow(new QLabel("透明度:", this), sliderOpacity); QFormLayout* formLayout3 = new QFormLayout(); formLayout3->addRow(new QLabel("显示拖拽方框:", this), checkShowDragSquare); formLayout3->addRow(new QLabel("拖拽方框尺寸:", this), editDragSquareEdge); formLayout3->addRow(new QLabel("拖拽方框颜色:", this), hDragSquareColorLayout); QFormLayout* formLayout4 = new QFormLayout(); formLayout4->addRow(new QLabel("显示边框:", this), checkShowRectBorder); formLayout4->addRow(new QLabel("边框颜色:", this), hRectBorderColorLayout); btnSavePreview = new QPushButton("保存", this); btnQuit = new QPushButton("退出", this); QHBoxLayout* btnLayout = new QHBoxLayout(); btnLayout->addStretch(); btnLayout->addWidget(btnSavePreview); btnLayout->addStretch(); btnLayout->addWidget(btnQuit); btnLayout->addStretch(); QVBoxLayout* vLayout = new QVBoxLayout(); vLayout->addLayout(formLayout1); vLayout->addStretch(); vLayout->addLayout(formLayout2); vLayout->addStretch(); vLayout->addLayout(formLayout3); vLayout->addStretch(); vLayout->addLayout(formLayout4); vLayout->addStretch(); vLayout->addLayout(btnLayout); mainLayout = new QHBoxLayout(this); mainLayout->addWidget(imgCropperLabel); mainLayout->addLayout(vLayout); } void ImageCropperDemo::init() { imgCropperLabel->setRectCropper(); editCropperFixedWidth->setEnabled(false); editCropperFixedHeight->setEnabled(false); editFixedWidth->setEnabled(false); editFixedHeight->setEnabled(false); labelPreviewImage->setFixedSize(96, 96); labelPreviewImage->setAlignment(Qt::AlignCenter); labelPreviewImage->setFrameStyle(QFrame::Panel | QFrame::Sunken); connect(imgCropperLabel, &ImageCropperLabel::croppedImageChanged, this, &ImageCropperDemo::onUpdatePreview); btnChooseOriginalImagePath->setIcon(QIcon(":/new/prefix1/images/select-file.ico")); btnChooseOriginalImagePath->setFixedWidth(30); connect(btnChooseOriginalImagePath, &QPushButton::clicked, this, &ImageCropperDemo::onChooseOriginalImage); comboOutputShape->addItem("矩形/长方形"); comboOutputShape->addItem("椭圆/圆"); connect(comboOutputShape, SIGNAL(currentIndexChanged(int)), this, SLOT(onOutputShapeChanged(int))); comboCropperShape->addItem("矩形"); comboCropperShape->addItem("正方形"); comboCropperShape->addItem("固定矩形尺寸"); comboCropperShape->addItem("椭圆"); comboCropperShape->addItem("圆"); comboCropperShape->addItem("固定椭圆尺寸"); connect(comboCropperShape, SIGNAL(currentIndexChanged(int)), this, SLOT(onCropperShapeChanged(int))); connect(editCropperFixedWidth, &QLineEdit::textChanged, this, &ImageCropperDemo::onFixedWidthChanged); connect(editCropperFixedHeight, &QLineEdit::textChanged, this, &ImageCropperDemo::onFixedHeightChanged); connect(editFixedWidth, &QLineEdit::textChanged, this, &ImageCropperDemo::onWidthChanged); connect(editFixedHeight, &QLineEdit::textChanged, this, &ImageCropperDemo::onHeightChanged); connect(editCropperMinWidth, &QLineEdit::textChanged, this, &ImageCropperDemo::onMinWidthChanged); connect(editCropperMinHeight, &QLineEdit::textChanged, this, &ImageCropperDemo::onMinHeightChanged); checkEnableOpacity->setCheckState(Qt::Checked); imgCropperLabel->enableOpacity(true); connect(checkEnableOpacity, &QCheckBox::stateChanged, this, &ImageCropperDemo::onEnableOpacityChanged); checkShowDragSquare->setCheckState(Qt::Checked); imgCropperLabel->setShowDragSquare(true); connect(checkShowDragSquare, &QCheckBox::stateChanged, this, &ImageCropperDemo::onShowDragSquareChanged); connect(editDragSquareEdge, &QLineEdit::textChanged, this, &ImageCropperDemo::onDragSquareEdgeChanged); sliderOpacity->setRange(0, 100); sliderOpacity->setValue(60); connect(sliderOpacity, &QSlider::valueChanged, this, &ImageCropperDemo::onOpacityChanged); checkShowRectBorder->setCheckState(Qt::Checked); connect(checkShowRectBorder, &QCheckBox::stateChanged, this, &ImageCropperDemo::onShowRectBorder); setLabelColor(labelRectBorderColor, Qt::white); btnChooseRectBorderCorlor->setIcon(QIcon(":/new/prefix1/images/color-palette.ico")); btnChooseRectBorderCorlor->setFixedWidth(40); connect(btnChooseRectBorderCorlor, &QPushButton::clicked, this, &ImageCropperDemo::onChooseRectBorderColor); setLabelColor(labelDragSquareColor, Qt::white); btnChooseDragSquareColor->setIcon(QIcon(":/new/prefix1/images/color-palette.ico")); btnChooseDragSquareColor->setFixedWidth(40); connect(btnChooseDragSquareColor, &QPushButton::clicked, this, &ImageCropperDemo::onChooseDragSquareColor); connect(btnSavePreview, &QPushButton::clicked, this, &ImageCropperDemo::onSaveCroppedImage); connect(btnQuit, &QPushButton::clicked, this, &ImageCropperDemo::close); imgCropperLabel->update(); } /***************************************************************************** * * slots * *****************************************************************************/ void ImageCropperDemo::onChooseOriginalImage() { QString filename = QFileDialog::getOpenFileName(this, "选择图片", "", "picture (*.jpg *.png *.bmp *.jpeg)"); if (filename.isNull()) return; QPixmap pixmap; if (!pixmap.load(filename)) { QMessageBox::critical(this, "Error", "加载图片失败!", QMessageBox::Ok); return; } editOriginalImagePath->setText(filename); imgCropperLabel->setOriginalImage(pixmap); imgCropperLabel->update(); onUpdatePreview(); labelPreviewImage->setFrameStyle(0); } void ImageCropperDemo::onOutputShapeChanged(int idx) { // Output: Rectangular if (idx == 0) imgCropperLabel->setOutputShape(OutputShape::RECT); else imgCropperLabel->setOutputShape(OutputShape::ELLIPSE); onUpdatePreview(); } void ImageCropperDemo::onCropperShapeChanged(int idx) { switch (CropperShape(idx + 1)) { case CropperShape::RECT: { imgCropperLabel->setRectCropper(); editCropperFixedWidth->setEnabled(false); editCropperFixedHeight->setEnabled(false); editFixedWidth->setEnabled(false); editFixedHeight->setEnabled(false); editCropperMinWidth->setEnabled(true); editCropperMinHeight->setEnabled(true); checkShowDragSquare->setEnabled(true); editDragSquareEdge->setEnabled(true); btnChooseDragSquareColor->setEnabled(true); break; } case CropperShape::SQUARE: { imgCropperLabel->setSquareCropper(); editCropperFixedWidth->setEnabled(false); editCropperFixedHeight->setEnabled(false); editFixedWidth->setEnabled(false); editFixedHeight->setEnabled(false); editCropperMinWidth->setEnabled(true); editCropperMinHeight->setEnabled(true); checkShowDragSquare->setEnabled(true); editDragSquareEdge->setEnabled(true); btnChooseDragSquareColor->setEnabled(true); break; } case CropperShape::FIXED_RECT: { imgCropperLabel->setFixedRectCropper(QSize(64, 64)); editCropperFixedWidth->setEnabled(true); editCropperFixedHeight->setEnabled(true); editFixedWidth->setEnabled(true); editFixedHeight->setEnabled(true); editCropperMinWidth->setEnabled(false); editCropperMinHeight->setEnabled(false); editCropperFixedWidth->setText("64"); editCropperFixedHeight->setText("64"); checkShowDragSquare->setEnabled(false); editDragSquareEdge->setEnabled(false); btnChooseDragSquareColor->setEnabled(false); break; } case CropperShape::ELLIPSE: { imgCropperLabel->setEllipseCropper(); editCropperFixedWidth->setEnabled(false); editCropperFixedHeight->setEnabled(false); editFixedWidth->setEnabled(false); editFixedHeight->setEnabled(false); editCropperMinWidth->setEnabled(true); editCropperMinHeight->setEnabled(true); checkShowDragSquare->setEnabled(true); editDragSquareEdge->setEnabled(true); btnChooseDragSquareColor->setEnabled(true); break; } case CropperShape::CIRCLE: { imgCropperLabel->setCircleCropper(); editCropperFixedWidth->setEnabled(false); editCropperFixedHeight->setEnabled(false); editFixedWidth->setEnabled(false); editFixedHeight->setEnabled(false); editCropperMinWidth->setEnabled(true); editCropperMinHeight->setEnabled(true); checkShowDragSquare->setEnabled(true); editDragSquareEdge->setEnabled(true); btnChooseDragSquareColor->setEnabled(true); break; } case CropperShape::FIXED_ELLIPSE: imgCropperLabel->setFixedEllipseCropper(QSize(64, 64)); editCropperFixedWidth->setEnabled(true); editCropperFixedHeight->setEnabled(true); editFixedWidth->setEnabled(true); editFixedHeight->setEnabled(true); editCropperMinWidth->setEnabled(false); editCropperMinHeight->setEnabled(false); editCropperFixedWidth->setText("64"); editCropperFixedHeight->setText("64"); checkShowDragSquare->setEnabled(false); editDragSquareEdge->setEnabled(false); btnChooseDragSquareColor->setEnabled(false); break; case CropperShape::UNDEFINED: break; } imgCropperLabel->update(); onUpdatePreview(); } void ImageCropperDemo::onEnableOpacityChanged(int state) { if (state == Qt::Checked) { sliderOpacity->setEnabled(true); imgCropperLabel->enableOpacity(true); } else { sliderOpacity->setEnabled(false); imgCropperLabel->enableOpacity(false); } imgCropperLabel->update(); } void ImageCropperDemo::onShowDragSquareChanged(int state) { if (state == Qt::Checked) { editDragSquareEdge->setEnabled(true); btnChooseDragSquareColor->setEnabled(true); imgCropperLabel->setShowDragSquare(true); } else { editDragSquareEdge->setEnabled(false); btnChooseDragSquareColor->setEnabled(false); imgCropperLabel->setShowDragSquare(false); } imgCropperLabel->update(); } void ImageCropperDemo::onDragSquareEdgeChanged(QString edge) { imgCropperLabel->setDragSquareEdge(edge.toInt()); imgCropperLabel->update(); } void ImageCropperDemo::onOpacityChanged(int val) { imgCropperLabel->setOpacity(val / 100.0); imgCropperLabel->update(); } void ImageCropperDemo::onFixedWidthChanged(QString width) { if(editCropperFixedWidth->hasFocus()){ int dpi=editResolution->text().toInt();//获取分辨率 double cm=width.toDouble()/dpi*2.54; editFixedWidth->setText(QString::number(cm,'f',1)); } imgCropperLabel->setCropperFixedWidth(width.toInt()); imgCropperLabel->update(); } void ImageCropperDemo::onFixedHeightChanged(QString height) { if(editCropperFixedHeight->hasFocus()){ int dpi=editResolution->text().toInt();//获取分辨率 int cm=height.toDouble()/dpi*2.54; editFixedHeight->setText(QString::number(cm,10)); } imgCropperLabel->setCropperFixedHeight(height.toInt()); imgCropperLabel->update(); } //厘米宽度事件 void ImageCropperDemo::onWidthChanged(QString width) { if(editFixedWidth->hasFocus()){ int dpi=editResolution->text().toInt();//获取分辨率 int px=width.toDouble()*dpi/2.54; editCropperFixedWidth->setText(QString::number(px,10)); } // imgCropperLabel->setCropperFixedWidth(width.toInt()); // imgCropperLabel->update(); } //厘米高度事件 void ImageCropperDemo::onHeightChanged(QString height) { if(editFixedHeight->hasFocus()){ int dpi=editResolution->text().toInt();//获取分辨率 int px=height.toDouble()*dpi/2.54; editCropperFixedHeight->setText(QString::number(px,10)); } // imgCropperLabel->setCropperFixedHeight(height.toInt()); // imgCropperLabel->update(); } void ImageCropperDemo::onMinWidthChanged(QString width) { imgCropperLabel->setCropperMinimumWidth(width.toInt()); imgCropperLabel->update(); } void ImageCropperDemo::onMinHeightChanged(QString height) { imgCropperLabel->setMinimumHeight(height.toInt()); imgCropperLabel->update(); } void ImageCropperDemo::onShowRectBorder(int state) { if (state == Qt::Checked) { btnChooseRectBorderCorlor->setEnabled(true); imgCropperLabel->setShowRectBorder(true); } else { btnChooseRectBorderCorlor->setEnabled(false); imgCropperLabel->setShowRectBorder(false); } imgCropperLabel->update(); } void ImageCropperDemo::onChooseRectBorderColor() { QColor color = QColorDialog::getColor(imgCropperLabel->getBorderPen().color(), this); if (color.isValid()) { setLabelColor(labelRectBorderColor, color); QPen pen = imgCropperLabel->getBorderPen(); pen.setColor(color); imgCropperLabel->setBorderPen(pen); imgCropperLabel->update(); } } void ImageCropperDemo::onChooseDragSquareColor() { QColor color = QColorDialog::getColor(Qt::white, this); if (color.isValid()) { setLabelColor(labelDragSquareColor, color); imgCropperLabel->setDragSquareColor(color); imgCropperLabel->update(); } } void ImageCropperDemo::onUpdatePreview() { QPixmap preview = imgCropperLabel->getCroppedImage(); preview = preview.scaled(labelPreviewImage->width(), labelPreviewImage->height(), Qt::KeepAspectRatio, Qt::SmoothTransformation); labelPreviewImage->setPixmap(preview); } void ImageCropperDemo::onSaveCroppedImage() { const QPixmap* pixmap = labelPreviewImage->pixmap(); if (!pixmap) { QMessageBox::information(this, "Error", "There is no cropped image to save.", QMessageBox::Ok); return ; } QString filename = QFileDialog::getSaveFileName(this, "保存图片", "", "picture (*.png)"); if (!filename.isNull()) { if (imgCropperLabel->getCroppedImage().save(filename, "PNG")) QMessageBox::information(this, "Prompt", "保存成功!", QMessageBox::Ok); else QMessageBox::information(this, "Error", "保存失败!", QMessageBox::Ok); } }