#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
#include <vtkSmartPointer.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkJPEGReader.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void openFileSlot();
private:
vtkSmartPointer<vtkRenderer> pRenderer0;
vtkSmartPointer<vtkRenderer> pRenderer1;
vtkSmartPointer<vtkRenderer> pRenderer2;
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <vtkRenderWindow.h>
#include <vtkPNGReader.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <vtkImageData.h>
#include <vtkImageViewer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageStencil.h>
#include <vtkImageStencilData.h>
#include <vtkImageLuminance.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
pRenderer0 = vtkSmartPointer<vtkRenderer>::New();
pRenderer0->SetBackground(1, 0, 0);
pRenderer0->SetViewport(0, 0, 0.33, 1);
pRenderer1 = vtkSmartPointer<vtkRenderer>::New();
pRenderer1->SetBackground(0, 1, 0);
pRenderer1->SetViewport(0.33, 0, 0.66, 1);
pRenderer2 = vtkSmartPointer<vtkRenderer>::New();
pRenderer2->SetBackground(0, 0, 1);
pRenderer2->SetViewport(0.66, 0, 1, 1);
ui->qvtkWidget->GetRenderWindow()->AddRenderer(pRenderer0);
ui->qvtkWidget->GetRenderWindow()->AddRenderer(pRenderer1);
ui->qvtkWidget->GetRenderWindow()->AddRenderer(pRenderer2);
connect(ui->pushButton, SIGNAL(clicked(bool)), this, SLOT(openFileSlot()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openFileSlot()
{
#if 1
QString selectFilePath = QFileDialog::getOpenFileName(this, QString("選擇圖像文件"), QString(""), QString("圖像(*.jpg)"));
#else
QString selectFilePath = QFileDialog::getOpenFileName(this, QString("選擇圖像文件"), QString(""), QString("圖像(*.png)"));
#endif
if(selectFilePath.isEmpty())
{
ui->textBrowser->append("選擇圖像路徑爲空!");
return ;
}
// 原始圖像
#if 1
vtkSmartPointer<vtkJPEGReader> pJpegReader = vtkSmartPointer<vtkJPEGReader>::New();
#else
vtkSmartPointer<vtkPNGReader> pJpegReader = vtkSmartPointer<vtkPNGReader>::New();
#endif
pJpegReader->SetFileName(selectFilePath.toStdString().c_str());
pJpegReader->Update();
vtkSmartPointer<vtkImageActor> pJpegActor = vtkSmartPointer<vtkImageActor>::New();
pJpegActor->SetInputData(pJpegReader->GetOutput());
pRenderer0->AddActor(pJpegActor);
double* bounds = pJpegActor->GetDisplayBounds();
qDebug() << "bounds = " << bounds[0] << ", " << bounds[1] << ", " << bounds[2] << ", " << bounds[3];
// vtkSmartPointer<vtkImageLuminance> pImageLuminance = vtkSmartPointer<vtkImageLuminance>::New();
// pImageLuminance->SetInputConnection(pJpegReader->GetOutputPort());
// pImageLuminance->Update();
// 模板
vtkSmartPointer<vtkImageCanvasSource2D> pImageCanvas = vtkSmartPointer<vtkImageCanvasSource2D>::New();
pImageCanvas->SetScalarTypeToUnsignedChar();
// 這樣寫OK
pImageCanvas->SetNumberOfScalarComponents(1);
pImageCanvas->SetExtent(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
pImageCanvas->SetDrawColor(255.0);
pImageCanvas->FillBox(bounds[0], bounds[1], bounds[2], bounds[3]);
pImageCanvas->SetDrawColor(0.0);
pImageCanvas->FillBox(bounds[1] / 4.0, bounds[1] * 3 / 4., bounds[3] / 4.0, bounds[3] * 3 / 4.);
pImageCanvas->Update();
// 這樣寫也OK
// pImageCanvas->SetNumberOfScalarComponents(3);
// pImageCanvas->SetExtent(bounds[0], bounds[1], bounds[2], bounds[3], bounds[4], bounds[5]);
// pImageCanvas->SetDrawColor(255.0, 255.0, 255.0);
// pImageCanvas->FillBox(bounds[0], bounds[1], bounds[2], bounds[3]);
// pImageCanvas->SetDrawColor(0.0, 0.0, 0.0);
// pImageCanvas->FillBox(bounds[1] / 4.0, bounds[1] * 3 / 4., bounds[3] / 4.0, bounds[3] * 3 / 4.);
// pImageCanvas->Update();
vtkSmartPointer<vtkImageActor> pCanavsActor = vtkSmartPointer<vtkImageActor>::New();
pCanavsActor->SetInputData(pImageCanvas->GetOutput());
pRenderer1->AddActor(pCanavsActor);
bounds = pCanavsActor->GetDisplayBounds();
qDebug() << "bounds = " << bounds[0] << ", " << bounds[1] << ", " << bounds[2] << ", " << bounds[3];
vtkSmartPointer<vtkImageStencil> pImageStencil = vtkSmartPointer<vtkImageStencil>::New();
pImageStencil->SetInputData(pImageCanvas->GetOutput());
// 圖像融合
vtkSmartPointer<vtkImageBlend> pImageBlend = vtkSmartPointer<vtkImageBlend>::New();
// 原始寫法:不報錯,融合不正確
// pImageBlend->SetInputData(pJpegReader->GetOutput());
// pImageBlend->SetInputData(pImageCanvas->GetOutput());
// 不報錯,融合不正確
// pImageBlend->SetInputData( pJpegReader->GetOutput());
// pImageBlend->SetInputData( pImageStencil->GetOutput());
// 不報錯,融合不正確
// pImageBlend->SetInputData(0, pJpegReader->GetOutput());
// pImageBlend->SetInputData(1, pImageStencil->GetStencil());
// 正確
pImageBlend->AddInputData( pJpegReader->GetOutput());
pImageBlend->AddInputData(pImageCanvas->GetOutput());
pImageBlend->SetOpacity(0, 0.3);
pImageBlend->SetOpacity(1, 0.7);
pImageBlend->Update();
vtkSmartPointer<vtkImageActor> pBlendActor = vtkSmartPointer<vtkImageActor>::New();
pBlendActor->SetInputData(pImageBlend->GetOutput());
pRenderer2->AddActor(pBlendActor);
// 不能在MainWidow的構造函數中
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
ui->qvtkWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle(style);
pRenderer0->ResetCamera();
pRenderer1->ResetCamera();
pRenderer2->ResetCamera();
ui->qvtkWidget->GetRenderWindow()->Render();
ui->textBrowser->append(QString("載入圖像:") + selectFilePath + QString(" 成功 !"));
}
QT UI文件
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="2,5">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>選擇圖像</string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="textBrowser"/>
</item>
</layout>
</item>
<item>
<widget class="QVTKWidget" name="qvtkWidget"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QVTKWidget</class>
<extends>QWidget</extends>
<header>QVTKWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>