c++ - Visual C++,带缩放、快照和捕获的 2D 绘图 Canvas 类

标签 c++ visual-c++ graphics 2d

我偶尔会开发科学模拟软件,并希望在 2D View 中可视化结果。

是否有任何现成的(最好是开源的)Win32 类可以创建绘图 Canvas

  1. 缩放,
  2. 快照和
  3. 可能具有视频捕捉功能?

我需要有限的 API,包括快速像素绘制、从内存缓冲区绘制 bmp 以及可能的文本。

最佳答案

一起看看 Qt 和 OpenGl。这是我经常使用的一些代码,可能对您有所帮助

//piview.h
#include <QGraphicsView>
#include <QGraphicsScene>


class PiView : public QGraphicsView{
    Q_OBJECT

  public:
    explicit PiView(QGraphicsScene * =0, QWidget *parent = 0);
    void enableSmoothRendering();
    void enableOpenGl();
    void fit();
    void renderToFile(QString const& path)const;


private:
    //void mouseMoveEvent(QMouseEvent *event);
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void wheelEvent(QWheelEvent *event);
    virtual void resizeEvent(QResizeEvent * event );

  signals:
    void pointRightClicked(QPointF) const;
    void pointLeftClicked(QPointF) const;
};
PiView* createMyPiView(QGraphicsScene* pScene);

//piview.cpp
#include "piview.h"

#ifdef OPENGL
#include <QtOpenGL>
#include <QGLWidget>
#endif


#include <QMouseEvent>
#include <QWheelEvent>

#include <qdebug.h>

PiView::PiView(QGraphicsScene* scene, QWidget *parent) : QGraphicsView(scene , parent){
  this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
  this->setDragMode(QGraphicsView::ScrollHandDrag);
}

void PiView::enableSmoothRendering(){
  this->setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing|QPainter::SmoothPixmapTransform);
}

#ifdef OPENGL
void  PiView::enableOpenGl(){
  QGLFormat fmt = QGLFormat::defaultFormat();
  fmt.setSampleBuffers(true);
  fmt.setDoubleBuffer(true);
  //fmt.setSamples(256);
  fmt.setDirectRendering(true);
  //qDebug() << "SampleBuffers:" << fmt.sampleBuffers() << fmt.samples();
  this->setViewport(new QGLWidget(fmt));
  this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
  this->setCacheMode(QGraphicsView::CacheBackground);
  //this->scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
}
#else
void PiView::enableOpenGl(){
  qDebug() << "Opengl was not enabled, enable it using opengl as qmake parameter";
}
#endif


void PiView::mousePressEvent(QMouseEvent *event){
  if (event->button()==Qt::RightButton) {
    emit pointRightClicked(mapToScene(event->pos()));
  }
  else if (event->button()==Qt::LeftButton) {
    emit pointLeftClicked(mapToScene(event->pos()));
  }
  QGraphicsView::mousePressEvent(event);
}

//Zooming using the mousewheel
void PiView::wheelEvent(QWheelEvent *event){
  double scaleFactor = 1.15; //How fast we zoom
  if (event->orientation()==Qt::Vertical){
    if(event->delta() > 0) {
      //Zoom in
      scale(scaleFactor, scaleFactor);
    } else {
      //Zooming out
      scale(1.0 / scaleFactor, 1.0 / scaleFactor);
    }
  }
  else if (event->orientation()==Qt::Horizontal) {
    if(event->delta() > 0) {
      scroll(10,0);
    }
    else {
      scroll(-10,0);
    }
  }
}

void PiView::resizeEvent(QResizeEvent *event){
  this->fit();
  QGraphicsView::resizeEvent(event);
}

void PiView::fit(){
  this->fitInView(this->sceneRect(),Qt::KeepAspectRatio);
}

PiView* createMyPiView(QGraphicsScene* pScene){
  PiView* view = new PiView(pScene);
  view->enableOpenGl();
  view->enableSmoothRendering();
  return view;
}

对于快照,请查看以下内容:

void SceneInteractor::saveSelection(){
  if (mpScene->selectedItems().isEmpty()) return;
  QList<QGraphicsItem*> items(mpScene->selectedItems());
  QRect sourceRect;
  boostForeach(QGraphicsItem*  item, items) {
    sourceRect = sourceRect.united(item->sceneBoundingRect().toRect());
  }
  QImage img(sourceRect.size(),QImage::Format_ARGB32_Premultiplied);
  img.fill(Qt::transparent);
  QPainter p(&img);
  p.setRenderHint(QPainter::Antialiasing);
  QGraphicsView::CacheMode cache = mpView->cacheMode();
  mpView->setCacheMode(QGraphicsView::CacheNone);
  mpView->scene()->clearSelection();
  mpView->scene()->render(&p, QRectF(), sourceRect);
  p.end();
  QString path = QFileDialog::getSaveFileName(0,tr("Choose Image-File Destination"));
  img.save(path,"PNG",100);
  mpView->setCacheMode(cache);
}

关于c++ - Visual C++,带缩放、快照和捕获的 2D 绘图 Canvas 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11071009/

相关文章:

c++ - 如何使用movntdqa避免缓存污染?

c++ - 为什么将 const 指针初始化为 null 时没有警告或错误?

c++ - COleDataSource/COleDropTarget 取消拖放操作

c++ - 错误 C2228 : left of '.push_back' must have class/struct/union

靠近相机时,Python 光线追踪会扭曲物体形状

java - AlphaComposite Transparency 重绘重叠成黑色

c++ - 返回的对象失去属性

c++ - 为什么 checked_array_iterator 在 VS2013 中不包含 <iterator> 就可以工作,但在 VS2017 中却失败了?

c++ - 模板类静态成员的初始化

graphics - 实现 API 以等待 d3d10 命令完成