zoukankan      html  css  js  c++  java
  • 一个 Qt 显示图片的控件(继承QWidget,使用QPixmap记录图像,最后在paintEvent进行绘制,可缩放)

    Qt 中没有专门显示图片的控件,通常我们会使用QLabel来显示图片。但是QLabel 显示图片的能力还是有点弱。比如不支持图像的缩放一类的功能,使用起来不是很方便。因此我就自己写了个简单的类。

    我这个类支持三种图像显示模式,我分别称之为:FIXED_SIZE, CENTRED,AUTO_ZOOM, AUTO_SIZE。

    • FIXED_SIZE 模式下,显示的图像大小等于图像尺寸乘以缩放因子,如果控件的尺寸小于这个大小则多出的部分被裁切掉。
    • FIX_SIZE_CENTRED模式与FIXED_SIZE 模式类似,但是,显示的图像居于窗口正中。
    • AUTO_ZOOM 模式下,显示的图像大小自动适应控件窗口大小。
    • AUTO_SIZE 模式下,这个控件的尺寸等于图像尺寸乘以缩放因子。

    下面是代码:

    [cpp] view plain copy
     
    1. #ifndef PICTUREBOX_H  
    2. #define PICTUREBOX_H  
    3.   
    4. #include <QWidget>  
    5. #include <QImage>  
    6. #include <QPixmap>  
    7.   
    8.   
    9. class PictureBox : public QWidget  
    10. {      
    11.     Q_OBJECT  
    12. public:  
    13.     enum PB_MODE {FIXED_SIZE, FIX_SIZE_CENTRED, AUTO_ZOOM, AUTO_SIZE};  
    14.     explicit PictureBox(QWidget *parent = 0);  
    15.     void setMode(PB_MODE mode);  
    16.     ~PictureBox();  
    17. private:  
    18.     QPixmap m_pixmap;  
    19.     double m_scale;  
    20.     PB_MODE m_mode;  
    21.     QBrush m_brush;  
    22. protected:  
    23.     void paintEvent(QPaintEvent * event);  
    24. signals:  
    25.   
    26. public slots:  
    27.     bool setImage(QImage &image, double scale = 1.0);  
    28.     void setBackground(QBrush brush);  
    29. };  
    30.   
    31. #endif // PICTUREBOX_H  
    [cpp] view plain copy
     
    1. #include "picturebox.h"  
    2. #include <QPainter>  
    3. #include <QDebug>  
    4. static const int IMAGE_WIDTH = 160;  
    5. static const int IMAGE_HEIGHT = 120;  
    6. static const QSize IMAGE_SIZE = QSize(IMAGE_WIDTH, IMAGE_HEIGHT);  
    7.   
    8. PictureBox::PictureBox(QWidget *parent) : QWidget(parent)  
    9. {  
    10.     m_pixmap = QPixmap(IMAGE_SIZE);  
    11.     m_pixmap.fill();  
    12.     m_scale = 1.0;  
    13.     m_mode = FIXED_SIZE;  
    14.     m_brush = QBrush(Qt::white);  
    15. }  
    16.   
    17. void PictureBox::setBackground(QBrush brush)  
    18. {  
    19.     m_brush = brush;  
    20.     update();  
    21. }  
    22.   
    23. void PictureBox::setMode(PB_MODE mode)  
    24. {  
    25.     m_mode = mode;  
    26.     if(m_mode == AUTO_SIZE)  
    27.     {  
    28.         setFixedSize(m_pixmap.size() * m_scale);  
    29.     }  
    30.     else  
    31.     {  
    32.         setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);  
    33.         setMinimumSize(0, 0);  
    34.     }  
    35.     update();  
    36. }  
    37.   
    38. bool PictureBox::setImage(QImage &image, double scale)  
    39. {  
    40.     if(image.isNull())  
    41.     {  
    42.         return false;  
    43.     }  
    44.     m_pixmap = QPixmap::fromImage(image);  
    45.     m_scale = qBound(0.01, scale, 100.0);  
    46.     if(m_mode == AUTO_SIZE)  
    47.     {  
    48.         setFixedSize(m_pixmap.size() * m_scale);  
    49.     }  
    50.     update();  
    51.     return true;  
    52. }  
    53.   
    54. void PictureBox::paintEvent(QPaintEvent * event)  
    55. {  
    56.     Q_UNUSED(event);  
    57.     QPainter painter(this);  
    58.     painter.setBackground(m_brush);  
    59.     painter.eraseRect(rect());  
    60.   
    61.     double window_width, window_height;  
    62.     double image_width, image_height;  
    63.     double r1, r2, r;  
    64.     int offset_x, offset_y;  
    65.     switch (m_mode)  
    66.     {  
    67.     case FIXED_SIZE:  
    68.     case AUTO_SIZE:  
    69.         painter.scale(m_scale, m_scale);  
    70.         painter.drawPixmap(0, 0, m_pixmap);  
    71.         break;  
    72.     case FIX_SIZE_CENTRED:  
    73.         window_width = width();  
    74.         window_height = height();  
    75.         image_width = m_pixmap.width();  
    76.         image_height = m_pixmap.height();  
    77.         offset_x = (window_width - m_scale * image_width) / 2;  
    78.         offset_y = (window_height - m_scale * image_height) / 2;  
    79.         painter.translate(offset_x, offset_y);  
    80.         painter.scale(m_scale, m_scale);  
    81.         painter.drawPixmap(0, 0, m_pixmap);  
    82.         break;  
    83.     case AUTO_ZOOM:  
    84.         window_width = width();  
    85.         window_height = height();  
    86.         image_width = m_pixmap.width();  
    87.         image_height = m_pixmap.height();  
    88.         r1 = window_width / image_width;  
    89.         r2 = window_height / image_height;  
    90.         r = qMin(r1, r2);  
    91.         offset_x = (window_width - r * image_width) / 2;  
    92.         offset_y = (window_height - r * image_height) / 2;  
    93.         painter.translate(offset_x, offset_y);  
    94.         painter.scale(r, r);  
    95.         painter.drawPixmap(0, 0, m_pixmap);  
    96.         break;  
    97.     }  
    98. }  
    99.   
    100. PictureBox::~PictureBox()  
    101. {  
    102.   
    103. }  

    AUTO_ZOOM 模式下显示例子如下:

    FIXED_SIZE 模式下的例子如下:

    FIX_SIZE_CENTRED 模式下的例子如下:

    http://blog.csdn.net/liyuanbhu/article/details/46687495

  • 相关阅读:
    ffmpeg中的sws_scale算法性能测试
    ffmpeg 新老接口问题及对照集锦
    入门视频采集与处理(显示YUV数据)
    RGB与YUV图像视频格式的相互转换
    ffmpeg视频解码简明教程
    FFmpeg源代码简单分析——sws_getContext()
    FFmpeg解码H264及swscale缩放详解
    我所理解的ThreadLocal
    网络通信Socket模块实现文件传输
    设计一个基于flask的高并发高可用的查询ip的http服务
  • 原文地址:https://www.cnblogs.com/findumars/p/6546096.html
Copyright © 2011-2022 走看看