主要提供两个类,第一个类显示静态图片,第二个类显示动态图片
两个类都包含图片缩小放大以及图片移动功能。
最后自己封装一个类,根据判断图片是动态还是静态去调用对应的类显示图片
效果展示:
判断图片类型
int showImage::getImageFormat(const QString & fileName)
{
//BMP格式特征码
unsigned char BMP_Format[] = { 0x42, 0x4d };
//JPG,JPEG格式特征码
unsigned char JPG_Format1[] = { 0xff, 0xd8, 0xff, 0xdb };
unsigned char JPG_Format2[] = { 0xff, 0xd8, 0xff, 0xe0 };
unsigned char JPG_Format3[] = { 0xff, 0xd8, 0xff, 0xe1 };
unsigned char JPG_Format4[] = { 0xff, 0xd8, 0xff, 0xe2 };
unsigned char JPG_Format5[] = { 0xff, 0xd8, 0xff, 0xe3 };
unsigned char JPG_Format6[] = { 0xff, 0xd8, 0xff, 0xe8 };
//GIF格式特征码
unsigned char GIF_Format1[] = { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 };
unsigned char GIF_Format2[] = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 };
//PNG格式特征码
unsigned char PNG_Format[] = { 0x89, 0x50, 0x4E, 0x47 };
int count = 0;
int step = 2;
//以二进制方式打开文件并读取前几个字节
unsigned char header[16];
std::ifstream readf(fileName.toStdString().c_str(), std::ios::binary);
if (!readf.is_open()) {
return E_Error;
}
//先读两个,判断是否BMP格式
for (int i = 0; i < step; i++) {
readf >> header[count + i];
}
count = count + step;
if (memcmp(header, BMP_Format, count) == 0) {
return E_Image;
}
//再读两个,判断是否JPG格式、PNG格式
for (int i = 0; i < step; i++) {
readf >> header[count + i];
}
count = count + step;
if ((memcmp(header, JPG_Format1, count) == 0)
|| (memcmp(header, JPG_Format2, count) == 0)
|| (memcmp(header, JPG_Format3, count) == 0)
|| (memcmp(header, JPG_Format4, count) == 0)
|| (memcmp(header, JPG_Format5, count) == 0)
|| (memcmp(header, JPG_Format6, count) == 0)) {
return E_Image;
}
else if (memcmp(header, PNG_Format, count) == 0) {
return E_Image;
}
//再读两个,判断是否GIF格式
for (int i = 0; i < step; i++) {
readf >> header[count + i];
}
count = count + step;
if ((memcmp(header, GIF_Format1, count) == 0)
|| (memcmp(header, GIF_Format2, count) == 0)) {
return E_GifImage;
}
return E_Error;
}
获取非动态图片尺寸
QSize showImage::getImageSize(const QString & fileName)
{
QImage image;
image.load(fileName);
int width = image.width();
int height = image.height();
return QSize(width, height);
}
获取动态图片尺寸
QSize showImage::getGifSize(const QString & fileName)
{
std::ifstream fp(fileName.toStdString().c_str(), std::ios::binary);
if (!fp) {
std::cout << "Can not open this file." << std::endl;
return QSize(0, 0);
}
char s1[2] = { 0 }, s2[2] = { 0 };
fp.seekg(6);
fp.read(s1, 2);
fp.read(s2, 2);
int width = (unsigned int)(s1[1]) << 8 | (unsigned int)(s1[0]);
int height = (unsigned int)(s2[1]) << 8 | (unsigned int)(s2[0]);
fp.close();
return QSize(width, height);
}
模仿qq图片查看效果
根据图片尺寸自适应显示图片,尺寸过大则会等比例优化显示
具有图片缩小放大功能,可移动图片
ImageView::ImageView(QWidget *parent)
{
}
ImageView::~ImageView()
{
}
void ImageView::toSetImageValue(QImage image)
{
m_image = image;
int height = qMax(image.height(), this->height());
int width = qMax(image.width(), this->width());
if (image.height() < image.width()) {
height = this->height();
width = image.width();
//width = height * 1.0 * (image.width() * 1.0 / image.height());
}
else {
width = this->width();
height = image.height();
//height = width * 1.0 / (image.width() * 1.0 / image.height());
}
m_image = image.scaled(width, height, Qt::KeepAspectRatio);
m_pixmap = QPixmap::fromImage(m_image);
m_imageSize = m_pixmap.size();
m_minImageSize = QSize(m_imageSize.width() / 10, m_imageSize.height() / 10);;
m_maxImageSize = QSize(m_imageSize.width() * 3, m_imageSize.height() * 3);
}
void ImageView::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
int NowW = m_imageSize.width();//现在的宽
int NowH = m_imageSize.height();
xPoint = width() / 2 - m_imageSize.width() / 2;
yPoint = height() / 2 - m_imageSize.height() / 2;
if (m_action == ImageView::Move) //移动
{
int offsetx = m_Alloffset.x() + m_offset.x();
m_Alloffset.setX(offsetx);//总偏移 x
int offsety = m_Alloffset.y() + m_offset.y();
m_Alloffset.setY(offsety); //总偏移 y
m_action = ImageView::None;
}
if (abs(m_Alloffset.x()) >= abs(xPoint)) //限制X偏移值
{
if (m_Alloffset.x() > 0)//右移
m_Alloffset.setX(abs(xPoint));//最大值
else//左移
m_Alloffset.setX(-abs(xPoint));
}
if (abs(m_Alloffset.y()) >= abs(yPoint)) //限制X偏移值
{
if (m_Alloffset.y() > 0)//右移
m_Alloffset.setY(abs(yPoint));//最大值
else//左移
m_Alloffset.setY(-abs(yPoint));
}
int x = width() / 2 + m_Alloffset.x() - m_imageSize.width() / 2;
if (x < 0)x = 0;
int y = height() / 2 + m_Alloffset.y() - m_imageSize.height() / 2;
if (y < 0)y = 0;
int sx = m_imageSize.width() / 2 - width() / 2 - m_Alloffset.x();
if (sx < 0)sx = 0;
int sy = m_imageSize.height() / 2 - height() / 2 - m_Alloffset.y();
if (sy < 0)sy = 0;
int w = (m_imageSize.width() - sx) > width() ? width() : (m_imageSize.width() - sx);
if (w > (width() - x))
w = width() - x;
int h = (m_imageSize.height() - sy) > height() ? height() : (m_imageSize.height() - sy);
if (h > (height() - y))
h = height() - y;
if ((xPoint > 0) && (yPoint > 0)) {
//这里清零,可以保证,放大以后拖动到其他位置后缩小,不会改变处于中下位置.
int offSetX = xPoint;
int offSetY = yPoint;
painter.drawPixmap(offSetX, offSetY, m_pixmap);
}
else {
painter.drawPixmap(x, y, w, h, m_pixmap, sx, sy, w, h);
}
}
void ImageView::wheelEvent(QWheelEvent *event)
{
QImage imgScaled;
int numDegrees = event->delta();
int numSteps = numDegrees;
if (m_imageSize == QSize(0, 0)) {
m_imageSize = m_image.size();
}
if ((m_imageSize.width() <= m_maxImageSize.width()) && \
(m_imageSize.height() <= m_maxImageSize.height()) && \
(m_imageSize.width() >= m_minImageSize.width()) && \
(m_imageSize.height() >= m_minImageSize.height())) {
if (numSteps > 0) {//向上滚动
imgScaled = m_image.scaled(m_imageSize.width() * 12 / 11, m_imageSize.height() * 12 / 11, Qt::KeepAspectRatio);
}
else {
imgScaled = m_image.scaled(m_imageSize.width() * 11 / 12, m_imageSize.height() * 11 / 12, Qt::KeepAspectRatio);
}
//给painter绘制图片
m_pixmap = QPixmap::fromImage(imgScaled);
m_imageSize = m_pixmap.size();
update();
//大于最大 只能缩小
}
else if ((m_imageSize.width() >= m_maxImageSize.width()) && \
(m_imageSize.height() >= m_maxImageSize.height()) && \
(numSteps < 0)) {
if (numSteps > 0) {//向上滚动
imgScaled = m_image.scaled(m_imageSize.width() * 12 / 11, m_imageSize.height() * 12 / 11, Qt::KeepAspectRatio);
}
else {
imgScaled = m_image.scaled(m_imageSize.width() * 11 / 12, m_imageSize.height() * 11 / 12, Qt::KeepAspectRatio);
}
//给painter绘制图片
m_pixmap = QPixmap::fromImage(imgScaled);
m_imageSize = m_pixmap.size();
update();
//小于最小,只能放大
}
else if ((m_imageSize.width() <= m_minImageSize.width()) && \
(m_imageSize.height() <= m_minImageSize.height() && \
(numSteps > 0))) {
if (numSteps > 0) {//向上滚动
imgScaled = m_image.scaled(m_imageSize.width() * 12 / 11, m_imageSize.height() * 12 / 11, Qt::KeepAspectRatio);
}
else {
imgScaled = m_image.scaled(m_imageSize.width() * 11 / 12, m_imageSize.height() * 11 / 12, Qt::KeepAspectRatio);
}
//给painter绘制图片
m_pixmap = QPixmap::fromImage(imgScaled);
m_imageSize = m_pixmap.size();
update();
}
}
void ImageView::mousePressEvent(QMouseEvent *event)
{
if (Qt::LeftButton == event->button()) {
m_bPressed = true;
m_preDotPos = event->pos();
}
QWidget::mousePressEvent(event);
}
void ImageView::mouseMoveEvent(QMouseEvent *event)
{
if ((event->buttons() & Qt::LeftButton) && m_bPressed && ((yPoint < 0) || (xPoint < 0))) {
this->setCursor(Qt::SizeAllCursor);
m_offset.setX(event->pos().x() - m_preDotPos.x());//偏移量 x
m_offset.setY(event->pos().y() - m_preDotPos.y());//偏移量 y
m_preDotPos = event->pos();//改变 前点
m_action = ImageView::Move;
event->accept();
update();
}
QWidget::mouseMoveEvent(event);
}
void ImageView::mouseReleaseEvent(QMouseEvent *event)
{
m_bPressed = false;
this->setCursor(Qt::ArrowCursor);
}
模仿qq图片查看效果
根据图片尺寸自适应显示图片,尺寸过大则会等比例优化显示
具有图片缩小放大功能,可移动图片
LabelGIF::LabelGIF(QWidget *parent)
: QLabel(parent)
{
setAlignment(Qt::AlignCenter);
setMovie(&m_movie);
}
LabelGIF::~LabelGIF()
{
}
void LabelGIF::setResource(const QString & path)
{
if (m_movie.state() == QMovie::Running) {
return;
}
m_movie.setFileName(path);
m_movie.start();
}
void LabelGIF::setScaledSize(const QSize & size)
{
setFixedSize(size);
m_movie.setScaledSize(size);
m_pSize = size;
}
void LabelGIF::setScaledSize(int w, int h)
{
QSize size(w, h);
setFixedSize(size);
m_movie.setScaledSize(size);
m_pSize = size;
}
void LabelGIF::mouseDoubleClickEvent(QMouseEvent *e)
{
emit sigMouseDoubleClick();
}
void LabelGIF::getPsize(int w, int h)
{
posWidth = w;
posHeight = h;
}
void LabelGIF::wheelEvent(QWheelEvent * event)
{
int value = event->delta();
double poxWidth = m_pSize.width();
double poxHeight = m_pSize.height();
if (value > 0)
{
if (m_pSize.width() > m_pSize.height()) {
poxWidth = m_pSize.width() + 10;
if (posWidth <= m_pSize.width())
poxWidth = posWidth;
poxHeight = poxWidth * ((float)m_pSize.height() / (float)m_pSize.width());
}
else
{
poxHeight = m_pSize.height() + 10;
if (posHeight <= m_pSize.height())
poxHeight = posHeight;
poxWidth = poxHeight * ((float)m_pSize.width() / (float)m_pSize.height());
}
// qInfo() << QStringLiteral("放大操作") << "poxHeight = " << poxHeight << "poxWidth = " << poxWidth;
}
else
{
if (m_pSize.width() > m_pSize.height()) {
poxWidth = m_pSize.width() - 10;
if (120 >= m_pSize.width())
poxWidth = 120;
poxHeight = poxWidth * ((float)m_pSize.height() / (float)m_pSize.width());
}
else
{
poxHeight = m_pSize.height() - 10;
if (120 >= m_pSize.height())
poxHeight = 120;
poxWidth = poxHeight * ((float)m_pSize.width() / (float)m_pSize.height());
}
// qInfo() << QStringLiteral("缩小操作") << "poxHeight = " << poxHeight << "poxWidth = " << poxWidth;
}
m_pSize = QSize(poxWidth, poxHeight);
setScaledSize(m_pSize);
}
void LabelGIF::mousePressEvent(QMouseEvent * event)
{
m_OldPos = event->pos();
m_Pressed = true;
}
void LabelGIF::mouseMoveEvent(QMouseEvent * event)
{
if (!m_Pressed)
return QWidget::mouseMoveEvent(event);
this->setCursor(Qt::SizeAllCursor);
QPoint pos = event->pos();
int xPtInterval = pos.x() - m_OldPos.x();
int yPtInterval = pos.y() - m_OldPos.y();
m_XPtInterval += xPtInterval;
m_YPtInterval += yPtInterval;
int moveX = this->x() + m_XPtInterval;
int moveY = this->y() + m_YPtInterval;
if (moveX < 0)
moveX = 0;
if (moveY < 0)
moveY = 0;
if ((moveX + m_pSize.width()) > posWidth)
moveX = posWidth - m_pSize.width();
if ((moveY + m_pSize.height()) > posHeight)
moveY = posHeight - m_pSize.height();
move(moveX, moveY);
m_OldPos = pos;
repaint();
}
void LabelGIF::mouseReleaseEvent(QMouseEvent * event)
{
m_Pressed = false;
this->setCursor(Qt::ArrowCursor);
}