#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPixmap>
#include <QTransform>
#include <QPushButton>
#include <QVBoxLayout>
#include <QResizeEvent>
#include <QDebug>
#include <QComboBox>
#include <iostream>
#include <cmath>
#include <string>
#include <algorithm>
#include <QtDebug>
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif
struct Rect {
double x, y; // 左上角坐标
double w, h; // 宽度和高度
};
enum class RotationPoint {
TOP_LEFT, TOP_CENTER, TOP_RIGHT,
CENTER_LEFT, CENTER, CENTER_RIGHT,
BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT
};
// 计算旋转后的矩形
Rect rotateRect(const Rect& rect, RotationPoint point, double angle) {
// 将角度转换为弧度
double radians = angle * M_PI / 180.0;
// 计算矩形的宽度和高度
double width = rect.w;
double height = rect.h;
// 计算旋转点的坐标
double centerX, centerY;
switch (point) {
case RotationPoint::TOP_LEFT: centerX = rect.x; centerY = rect.y; break;
case RotationPoint::TOP_CENTER: centerX = rect.x + width / 2; centerY = rect.y; break;
case RotationPoint::TOP_RIGHT: centerX = rect.x + width; centerY = rect.y; break;
case RotationPoint::CENTER_LEFT: centerX = rect.x; centerY = rect.y + height / 2; break;
case RotationPoint::CENTER: centerX = rect.x + width / 2; centerY = rect.y + height / 2; break;
case RotationPoint::CENTER_RIGHT: centerX = rect.x + width; centerY = rect.y + height / 2; break;
case RotationPoint::BOTTOM_LEFT: centerX = rect.x; centerY = rect.y + height; break;
case RotationPoint::BOTTOM_CENTER: centerX = rect.x + width / 2; centerY = rect.y + height; break;
case RotationPoint::BOTTOM_RIGHT: centerX = rect.x + width; centerY = rect.y + height; break;
}
// 计算旋转后的四个角的坐标
double cosTheta = cos(radians);
double sinTheta = sin(radians);
// 左上角
double x1_rot = centerX + (rect.x - centerX) * cosTheta - (rect.y - centerY) * sinTheta;
double y1_rot = centerY + (rect.x - centerX) * sinTheta + (rect.y - centerY) * cosTheta;
// 右上角
double x2_rot = centerX + (rect.x + width - centerX) * cosTheta - (rect.y - centerY) * sinTheta;
double y2_rot = centerY + (rect.x + width - centerX) * sinTheta + (rect.y - centerY) * cosTheta;
// 左下角
double x3_rot = centerX + (rect.x - centerX) * cosTheta - (rect.y + height - centerY) * sinTheta;
double y3_rot = centerY + (rect.x - centerX) * sinTheta + (rect.y + height - centerY) * cosTheta;
// 右下角
double x4_rot = centerX + (rect.x + width - centerX) * cosTheta - (rect.y + height - centerY) * sinTheta;
double y4_rot = centerY + (rect.x + width - centerX) * sinTheta + (rect.y + height - centerY) * cosTheta;
// 计算旋转后的矩形的边界
double minX = std::min({x1_rot, x2_rot, x3_rot, x4_rot});
double maxX = std::max({x1_rot, x2_rot, x3_rot, x4_rot});
double minY = std::min({y1_rot, y2_rot, y3_rot, y4_rot});
double maxY = std::max({y1_rot, y2_rot, y3_rot, y4_rot});
// 返回旋转后的矩形
return {minX, minY, maxX - minX, maxY - minY};
}
void GetRoteDiff(RotationPoint point, int w, int h, int &x_diff, int &y_diff)
{
switch (point) {
case RotationPoint::TOP_LEFT:
x_diff = 0 ; y_diff = 0;break;
case RotationPoint::TOP_CENTER:
x_diff = w / 2 ; y_diff = 0;break;
case RotationPoint::TOP_RIGHT:
x_diff = w ; y_diff = 0;break;
case RotationPoint::CENTER_LEFT:
x_diff = 0 ; y_diff = h/2;break;
case RotationPoint::CENTER:
x_diff = w/2 ; y_diff = h/2;break;
case RotationPoint::CENTER_RIGHT:
x_diff = w ; y_diff = h/2;break;
case RotationPoint::BOTTOM_LEFT:
x_diff = 0 ; y_diff = h;break;
case RotationPoint::BOTTOM_CENTER:
x_diff = w/2 ; y_diff = h;break;
case RotationPoint::BOTTOM_RIGHT:
x_diff = w ; y_diff = h;break;
}
}
class ImageWidget : public QWidget {
public:
ImageWidget(const QString& imagePath, QWidget* parent = nullptr)
: QWidget(parent), rotationAngle(0) {
// 加载图像并缩放为 320x320
pixmap = QPixmap(imagePath).scaled(320, 320, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
orgPt = QPoint(340, 340);
orgRc = rect();
orgRc.setWidth(320);
orgRc.setHeight(320);
// 初始化窗口大小
updateBoundingRect(RotationPoint::TOP_CENTER);
QPalette palette;
palette.setColor(QPalette::Window, Qt::green); // 设置背景颜色为蓝色
// 将 QPalette 应用到窗口
setPalette(palette);
// 设置窗口的背景模式为窗口背景
setAutoFillBackground(true);
}
protected:
void paintEvent(QPaintEvent* event) override {
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 平移到窗口中心
painter.translate(-rc.x + x_diff, -rc.y + y_diff);
// 旋转指定角度
painter.rotate(rotationAngle);
// 绘制图像
painter.drawPixmap(-x_diff, -y_diff, pixmap);
}
void resizeEvent(QResizeEvent* event) override {
Q_UNUSED(event);
// 确保图像在窗口中居中
update();
}
private:
void updateBoundingRect(RotationPoint rt) {
this->rt = rt;
Rect rect = {0, 0, 320, 320}; // 原始矩形
RotationPoint point = rt; // 旋转点为中心
double angle = rotationAngle; // 旋转角度
Rect rotatedRect = rotateRect(rect, point, angle);
//qDebug() << "rotatedRect" << rotatedRect;
// 调整窗口大小
setGeometry(orgPt.x() + rotatedRect.x, orgPt.y() + rotatedRect.y,
rotatedRect.w,
rotatedRect.h);
rc = rotatedRect;
GetRoteDiff(rt, orgRc.width(), orgRc.height(), x_diff, y_diff);
}
void rotateImage(RotationPoint rt) {
rotationAngle += 30;
if (rotationAngle >= 360) {
rotationAngle -= 360;
}
updateBoundingRect(rt);
update(); // 触发重绘
}
friend class ControlWidget;
private:
QPixmap pixmap;
int rotationAngle;
QPoint orgPt;
QRect orgRc;
Rect rc;
RotationPoint rt;
int x_diff;
int y_diff;
};
class ControlWidget : public QWidget {
public:
ControlWidget(QWidget* parent = nullptr)
: QWidget(parent){
// 修改图像路径为 C:\\Users\\zzu\\Desktop\\1.jpg
imageWidget = new ImageWidget("C:\\Users\\zzu\\Desktop\\1.jpg", this);
imageWidget->move(340,340);
imageWidget->resize(320,320);
// 创建按钮
QPushButton* rotateButton = new QPushButton("Rotate", this);
connect(rotateButton, &QPushButton::clicked, this, &ControlWidget::rotateImage);
combo = new QComboBox(this);
combo->addItem("TOP_LEFT");
combo->addItem("TOP_CENTER");
combo->addItem("TOP_RIGHT");
combo->addItem("CENTER_LEFT");
combo->addItem("CENTER");
combo->addItem("CENTER_RIGHT");
combo->addItem("BOTTOM_LEFT");
combo->addItem("BOTTOM_CENTER");
combo->addItem("BOTTOM_RIGHT");
combo->setCurrentIndex(0);
// 设置布局
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(combo);
layout->addWidget(rotateButton);
setLayout(layout);
QPalette palette;
palette.setColor(QPalette::Window, Qt::blue); // 设置背景
zhoutianyou
- 粉丝: 160
- 资源: 13
最新资源
- 基于springboot+vue的汽车资讯网站(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的人口老龄化社区服务与管理平台(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的洗衣店订单管理系统(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的小徐影城管理系统(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的社团管理系统(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的校园周边美食探索及分享平台的设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的校园资料分享平台(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的校园资料分享平台2(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的社区医院管理系统(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的社区智慧养老监护管理平台设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的星之语明星周边产品销售网站的设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的新闻推荐系统(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的信息化在线教学平台的设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的体育馆使用预约平台的设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的图书电子商务网站的设计与实现(Java毕业设计,附源码,部署教程).zip
- 基于springboot+vue的学生宿舍管理系统的设计与开发(Java毕业设计,附源码,部署教程).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈