增加图片切割功能

This commit is contained in:
sonichy 2025-07-08 19:28:23 +08:00
parent dbdb484ab5
commit cd947cc7f7
4 changed files with 97 additions and 4 deletions

BIN
HTYPaint

Binary file not shown.

View File

@ -239,7 +239,7 @@ QColor MainWindow::intToColor(int intColor)
void MainWindow::on_action_changelog_triggered()
{
QString s = "1.27\n(2025-04)\n边缘裁剪后显示图片尺寸信息。\n取色显示RGB值。\n\n1.26\n(2024-08)\n优化边缘裁剪1次可以裁剪4边。\n\n1.25\n(2024-07)\n增加画线段。\n增加选框固定比例。\n\n1.24\n(2024-03)\n增加虚线样式。\n\n1.23\n(2023-03)\n增加边缘裁剪。\n\n1.22\n(2022-11)\n边框和填充可以分开取色。\n\n1.21\n(2022-10)\n增加对比度调整。\n\n1.20\n(2022-05)\n关闭时保存设置,打开时读取设置。\n\n1.19\n(2021-04)\n修复缩放锯齿问题。\n\n1.18\n(2020-12)\n如果粘贴的图片比当前图片大,询问是否扩张,然后处理。\n\n1.17\n(2020-04)\n修复:上个选区残留问题。\n增加:第一次全选可以填充颜色(因路径不能清空只能填充一次,再次填充需要关闭再打开)。\n\n1.16\n(2020-03)\n增加:圆形路径裁剪。\n背景文字改成了描边文字。\n\n1.15\n(2019-11)\n增加:文字工具可以绘制矩形背景。\n\n1.14\n(2019-08)\n增加:颜色调节。\n修复:选择颜色取消时颜色变黑色。\n\n1.13\n(2019-06)\n修复:选区裁剪大小微差。删除选区操作后没有设置回到框选工具。\n优化信息内容、选区裁剪。群组工具栏Action实现互斥Checked。\n增加画线长度信息画框长、宽信息微调显示信息裁剪后滚动条回到0。\n\n1.12\n(2019-05)\n修复PNG转灰度图透明度丢失。\n\n1.11\n(2019-04)\n修改:删除选取填充,白色改成透明色。\n增加:棋盘背景。\n增加:鼠标移动定位文字。\n增加Ctrl+鼠标滚轮 改变线粗或字体大小。\n\n1.10\n(2018-12)\n增加:选区马赛克。\n\n1.9\n(2018-11)\n增加:画笔粗细快捷键,画图更加方便。\n\n1.8\n(2018-05)\n修复:删除选区有虚线框,从右键打开方式无法打开文件。\n\n1.7\n(2017-11)\n颜色透明工具,取色后在边框色、填充色显示,超出边界清空鼠标位置信息。\n增加灰色背景,凸显绘图区域。\n优化代码。\n(2017-10)\n简化工具信号简化setCursor()。\n(2017-09)\n增加箭头工具。\n增加抗锯齿。\n\n1.6\n(2017-07)\n更新日志消息窗口写不下了,改成带滚动条的文本框。\n自定义信号结合事件过滤器,把鼠标移动位置发送到主窗体信息栏。\n增加拖放打开文件。\n(2017-06)\n使用自定义信号解决子类发信息给主窗体状态栏问题致谢rekols。\n(2017-05)\n右键打开文件记忆文件路径。\n\n1.5 (2017-04)\n透明色反色不改变。\n增加取色工具,橡皮擦颜色不再固定为白色,而是填充色。\n\n1.4 (2017-03)\n支持命令行打开文件和打开方式打开文件。\n修复鼠标指针引用本地文件没引用资源文件引起启动path参数改变不能加载图标的问题。\n菜单的SIGNAL-SLOT改为on_action_triggered()\n修复PNG图片裁剪丢失透明度问题。\n新建图像为透明图像。\n\n1.3 (2017-03)\n实现选区模糊。\n加入模糊滤镜。\n\n1.2 (2017-02)\n文件名显示在窗口标题栏。\n区别保存和另存为。\n增加导入图片。\n\n1.1 (2017-01)\n新增灰度、反色。\n\n1.0 (2017-01)\n解决删除选区后画不出选框的问题。\n恢复撤销。\n增加全选。\n实现选区或剪贴板移动!\n保存时自动获取打开文件的路径。\n增加按像素、比例缩放。\n实现在属性窗口设置画布大小。\n2016-12\n增加快捷键控制选框及其边框移动。\n绘图代码从MainWindow向imageWidget迁移。\n实现水平镜像、垂直镜像。\n实现放大、缩小、原始大小。\n为了增加滚动条增加自定义imageWidget。\n状态栏显示绘图详情。\n复制选区到系统剪贴板,从系统剪贴板获取图像粘贴。\n优化颜色选择交互。\n增加撤销、重做功能有BUG。\n设为壁纸。\n画选区,剪裁选区。\n新建图片,打开图片,保存图片。\n实现画点、线、框、圆、字。";
QString s = "1.28\n(2025-07)\n增加图片切割功能。\n\n1.27\n(2025-04)\n边缘裁剪后显示图片尺寸信息。\n取色显示RGB值。\n\n1.26\n(2024-08)\n优化边缘裁剪1次可以裁剪4边。\n\n1.25\n(2024-07)\n增加画线段。\n增加选框固定比例。\n\n1.24\n(2024-03)\n增加虚线样式。\n\n1.23\n(2023-03)\n增加边缘裁剪。\n\n1.22\n(2022-11)\n边框和填充可以分开取色。\n\n1.21\n(2022-10)\n增加对比度调整。\n\n1.20\n(2022-05)\n关闭时保存设置,打开时读取设置。\n\n1.19\n(2021-04)\n修复缩放锯齿问题。\n\n1.18\n(2020-12)\n如果粘贴的图片比当前图片大,询问是否扩张,然后处理。\n\n1.17\n(2020-04)\n修复:上个选区残留问题。\n增加:第一次全选可以填充颜色(因路径不能清空只能填充一次,再次填充需要关闭再打开)。\n\n1.16\n(2020-03)\n增加:圆形路径裁剪。\n背景文字改成了描边文字。\n\n1.15\n(2019-11)\n增加:文字工具可以绘制矩形背景。\n\n1.14\n(2019-08)\n增加:颜色调节。\n修复:选择颜色取消时颜色变黑色。\n\n1.13\n(2019-06)\n修复:选区裁剪大小微差。删除选区操作后没有设置回到框选工具。\n优化信息内容、选区裁剪。群组工具栏Action实现互斥Checked。\n增加画线长度信息画框长、宽信息微调显示信息裁剪后滚动条回到0。\n\n1.12\n(2019-05)\n修复PNG转灰度图透明度丢失。\n\n1.11\n(2019-04)\n修改:删除选取填充,白色改成透明色。\n增加:棋盘背景。\n增加:鼠标移动定位文字。\n增加Ctrl+鼠标滚轮 改变线粗或字体大小。\n\n1.10\n(2018-12)\n增加:选区马赛克。\n\n1.9\n(2018-11)\n增加:画笔粗细快捷键,画图更加方便。\n\n1.8\n(2018-05)\n修复:删除选区有虚线框,从右键打开方式无法打开文件。\n\n1.7\n(2017-11)\n颜色透明工具,取色后在边框色、填充色显示,超出边界清空鼠标位置信息。\n增加灰色背景,凸显绘图区域。\n优化代码。\n(2017-10)\n简化工具信号简化setCursor()。\n(2017-09)\n增加箭头工具。\n增加抗锯齿。\n\n1.6\n(2017-07)\n更新日志消息窗口写不下了,改成带滚动条的文本框。\n自定义信号结合事件过滤器,把鼠标移动位置发送到主窗体信息栏。\n增加拖放打开文件。\n(2017-06)\n使用自定义信号解决子类发信息给主窗体状态栏问题致谢rekols。\n(2017-05)\n右键打开文件记忆文件路径。\n\n1.5 (2017-04)\n透明色反色不改变。\n增加取色工具,橡皮擦颜色不再固定为白色,而是填充色。\n\n1.4 (2017-03)\n支持命令行打开文件和打开方式打开文件。\n修复鼠标指针引用本地文件没引用资源文件引起启动path参数改变不能加载图标的问题。\n菜单的SIGNAL-SLOT改为on_action_triggered()\n修复PNG图片裁剪丢失透明度问题。\n新建图像为透明图像。\n\n1.3 (2017-03)\n实现选区模糊。\n加入模糊滤镜。\n\n1.2 (2017-02)\n文件名显示在窗口标题栏。\n区别保存和另存为。\n增加导入图片。\n\n1.1 (2017-01)\n新增灰度、反色。\n\n1.0 (2017-01)\n解决删除选区后画不出选框的问题。\n恢复撤销。\n增加全选。\n实现选区或剪贴板移动!\n保存时自动获取打开文件的路径。\n增加按像素、比例缩放。\n实现在属性窗口设置画布大小。\n2016-12\n增加快捷键控制选框及其边框移动。\n绘图代码从MainWindow向imageWidget迁移。\n实现水平镜像、垂直镜像。\n实现放大、缩小、原始大小。\n为了增加滚动条增加自定义imageWidget。\n状态栏显示绘图详情。\n复制选区到系统剪贴板,从系统剪贴板获取图像粘贴。\n优化颜色选择交互。\n增加撤销、重做功能有BUG。\n设为壁纸。\n画选区,剪裁选区。\n新建图片,打开图片,保存图片。\n实现画点、线、框、圆、字。";
QDialog *dialog = new QDialog;
dialog->setWindowTitle("更新历史");
dialog->setFixedSize(400,300);
@ -269,7 +269,7 @@ void MainWindow::on_action_aboutQt_triggered()
void MainWindow::on_action_about_triggered()
{
QMessageBox aboutMB(QMessageBox::NoIcon, "关于", "海天鹰画图 1.27\n一款基于 Qt 的画图程序。\n作者:海天鹰\nE-mail: sonichy@163.com\n主页https://gitlink.org.cn/sonichy/HTYPaint\n参考文献:\n绘图:\nhttp://tzc.is-programmer.com/posts/534.html\nhttp://lizhigg.love.blog.163.com/blog/static/62611781201222105550184/\n滚动条http://down.51cto.com/data/233634\n灰度图http://www.cnblogs.com/xianglan/archive/2010/12/24/1915905.html\n拖放打开文件http://blog.csdn.net/rl529014/article/details/53057577\nColor与Int类型相互转换https://blog.csdn.net/snowdream86/article/details/5273757");
QMessageBox aboutMB(QMessageBox::NoIcon, "关于", "海天鹰画图 1.28\n一款基于 Qt 的画图程序。\n作者:海天鹰\nE-mail: sonichy@163.com\n主页https://gitlink.org.cn/sonichy/HTYPaint\n参考文献:\n绘图:\nhttp://tzc.is-programmer.com/posts/534.html\nhttp://lizhigg.love.blog.163.com/blog/static/62611781201222105550184/\n滚动条http://down.51cto.com/data/233634\n灰度图http://www.cnblogs.com/xianglan/archive/2010/12/24/1915905.html\n拖放打开文件http://blog.csdn.net/rl529014/article/details/53057577\nColor与Int类型相互转换https://blog.csdn.net/snowdream86/article/details/5273757");
aboutMB.setIconPixmap(QPixmap(":/icon/HTYPaint.png"));
aboutMB.exec();
}
@ -1160,6 +1160,15 @@ void MainWindow::on_action_cutBorder_triggered()
spinBox_bottom->setValue(0);
spinBox_bottom->setRange(0, ry);
gridLayout->addWidget(spinBox_bottom, 2, 1);
QPushButton *pushButton_restore = new QPushButton;
pushButton_restore->setIcon(QIcon::fromTheme("view-refresh"));
connect(pushButton_restore, &QPushButton::clicked, [=]{
spinBox_top->setValue(0);
spinBox_left->setValue(0);
spinBox_right->setValue(0);
spinBox_bottom->setValue(0);
});
gridLayout->addWidget(pushButton_restore, 1, 1);
vbox->addLayout(gridLayout);
QPushButton *pushButton_confirm = new QPushButton("确定");
@ -1211,3 +1220,79 @@ void MainWindow::on_action_dashPattern_triggered()
imageWidget->pen.setDashPattern(pattern);
}
}
void MainWindow::on_action_slice_triggered()
{
QDialog *dialog = new QDialog(this);
dialog->setWindowTitle("切割");
dialog->setFixedSize(200, 150);
QVBoxLayout *vbox = new QVBoxLayout;
QHBoxLayout *hbox = new QHBoxLayout;
QLabel *label = new QLabel("方向");
hbox->addWidget(label);
QComboBox *comboBox = new QComboBox;
QStringList SL_direction;
SL_direction << "竖向" << "横向";
comboBox->addItems(SL_direction);
hbox->addWidget(comboBox);
vbox->addLayout(hbox);
hbox = new QHBoxLayout;
label = new QLabel("份数");
hbox->addWidget(label);
QLineEdit *lineEdit = new QLineEdit;
QString sn = settings.value("Slice", "5").toString();
lineEdit->setText(sn);
hbox->addWidget(lineEdit);
vbox->addLayout(hbox);
label = new QLabel;
label->setAlignment(Qt::AlignCenter);
vbox->addWidget(label);
connect(comboBox, &QComboBox::currentTextChanged, [=]{
label->setText("");
});
connect(lineEdit, &QLineEdit::textChanged, [=]{
label->setText("");
});
QPushButton *pushButton_confirm = new QPushButton("确定");
QPushButton *pushButton_cancel = new QPushButton("取消");
hbox = new QHBoxLayout;
hbox->addStretch();
hbox->addWidget(pushButton_confirm);
hbox->addWidget(pushButton_cancel);
hbox->addStretch();
vbox->addLayout(hbox);
dialog->setLayout(vbox);
dialog->show();
connect(pushButton_confirm, &QPushButton::clicked, [=]{
bool b;
int n = lineEdit->text().toInt(&b, 10);
if (b) {
for (int i=0; i<n; i++) {
QImage image;
if (comboBox->currentIndex() == 0) {
int dy = imageWidget->image.height() / n;
image = imageWidget->image.copy(0, dy * i, imageWidget->image.width(), dy);
} else if (comboBox->currentIndex() == 1) {
int dx = imageWidget->image.width() / n;
image = imageWidget->image.copy(dx * i, 0, dx, imageWidget->image.height());
}
QString fp = "";
if (path == "")
fp = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/" + comboBox->currentText() + QString::number(i) + ".png";
else
fp = QFileInfo(path).path() + "/" + QFileInfo(filename).baseName() + comboBox->currentText() + QString::number(i) + "." + QFileInfo(filename).suffix();
//qDebug() << fp;
image.save(fp, nullptr, 100);
label->setText("切割:" + comboBox->currentText() + " " + QString::number(i+1) + "/" + QString::number(n));
}
settings.setValue("Slice", lineEdit->text());
} else {
QMessageBox::critical(dialog, "错误", "份数不是数字");
}
});
connect(pushButton_cancel, &QPushButton::clicked, [=]{
dialog->close();
});
}

View File

@ -37,6 +37,7 @@
#include <QShortcut>
#include <QSettings>
#include <QMetaEnum>
#include <QStandardPaths>
namespace Ui {
class MainWindow;
@ -53,11 +54,11 @@ public:
QToolButton *toolButton_color_border, *toolButton_color_fill;
QLineEdit *lineEdit;
QSpinBox *spinbox_penWidth, *spinw, *spinwr, *spinh, *spinhr;
QString text, path;
QCheckBox *checkBox_color_fill, *checkBox_color_border;
QComboBox *comboBox_penStyle, *comboBox_selectRatio;
QLabel *LSB1,*LSB2;
QFont font;
QString text, path;
QString filename;
protected:
@ -103,6 +104,7 @@ private slots:
void on_action_deleteBlackBorder_triggered();
void on_action_cutBorder_triggered();
void on_action_dashPattern_triggered();
void on_action_slice_triggered();
void on_actionRotateLeft_triggered();
void on_actionRotateRight_triggered();

View File

@ -75,6 +75,7 @@
<addaction name="action_deleteBlackBorder"/>
<addaction name="action_cutBorder"/>
<addaction name="action_dashPattern"/>
<addaction name="action_slice"/>
</widget>
<widget class="QMenu" name="menu_about">
<property name="title">
@ -757,6 +758,11 @@
<string>polyline</string>
</property>
</action>
<action name="action_slice">
<property name="text">
<string>切割</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>