从 GDALDataSet 创建一个 RBG Color QImage
create an RBG Color QImage from a GDALDataSet
我使用 GDAL
读取一些图像文件并希望使用 Qt
显示它们。到目前为止,我设法为 GDALDataSet
中的每个 GDALRasterBand
创建了灰度 QImage
,但我不知道如何创建单个 RGB 图像。
这是我所做的:
#include <gdal_priv.h>
#include <QtGui\QImage>
int main(int argc, char *argv[])
{
GDALAllRegister();
GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen("path_to_some_image.tif", GA_ReadOnly));
int size_out = 200;
for (int i = 1; i <= 3; ++i)
{
GDALRasterBand* band = dataset->GetRasterBand(i);
std::vector<uchar> band_data(size_out * size_out);
band->RasterIO(GF_Read, 0, 0, size_out, size_out, band_data.data(), size_out, size_out, GDT_Byte, 0, 0);
QImage band_image(band_data.data(), size_out, size_out, QImage::Format_Grayscale8);
band_image.save(QString("C:\band_%1.png").arg(i));
}
return 0;
}
如何读取数据以便创建单个 RGB QImage
?
你快到了。第一项是 QImage 使用带有格式标志的缓冲区。因此,该格式标志需要匹配您从文件加载的图像,否则需要进行转换。下面的示例假设一个 4 通道图像。
QImage 格式标志文档:http://doc.qt.io/qt-5/qimage.html#Format-enum
下一个组成部分是 GDAL 的 RasterIO
方法分别处理每个波段,这意味着您必须分别交错像素,否则会失去逐个加载栅格带来的效率。
光栅IO:http://gdal.org/classGDALRasterBand.html#a30786c81246455321e96d73047b8edf1
我喜欢 OpenCV 的 merge
方法。只需为每个波段创建一个灰度图像并将它们 merge
放在一起。
OpenCV 合并:http://docs.opencv.org/3.0.0/d2/de8/group__core__array.html#ga61f2f2bde4a0a0154b2333ea504fab1d
例如,给定一个 RGBA GeoTiff,
// OpenCV Libraries
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// GDAL Libraries
#include <gdal.h>
// QT Libraries
#include <QtGui\QImage>
using namespace cv;
int main( int argc, char* argv[] )
{
// Initialize GDAL
GDALAllRegister();
// Load image
GDALDataset* dataset = GDALOpen("path_to_some_image.tif", GA_ReadOnly);
// Get raster image size
int rows = dataset->GetRasterYSize();
int cols = dataset->GetRasterXSize();
int channels = dataset->GetRasterCount();
// Create each separate image as grayscale
std::vector<cv::Mat> image_list(channels, cv::Mat( rows, cols, CV_8UC1 ));
cv::Mat output_image;
// Iterate over each channel
for (int i = 1; i <= channels; ++i)
{
// Fetch the band
GDALRasterBand* band = dataset->GetRasterBand(i);
// Read the data
band->RasterIO( GF_Read, 0, 0,
cols, rows,
image_list[i-1].data,
cols, rows,
GDT_Byte, 0, 0);
}
// Merge images
cv::merge( image_list, output_image );
// Create the QImage
QImage qt_image( band_data.data(),
cols,
rows,
QImage::Format_RGBA8888);
// Do some stuff with the image
return 0;
}
没有 OpenCV,使用 msmith81886 代码:
// Load image
GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen(tifFile.toLocal8Bit().data(), GA_ReadOnly));
// Get raster image size
int rows = dataset->GetRasterYSize();
int cols = dataset->GetRasterXSize();
int channels = dataset->GetRasterCount();
std::vector<std::vector<uchar>> bandData(channels);
for (auto& mat : bandData)
{
mat.resize(size_t(rows * cols));
}
std::vector<uchar> outputImage(size_t(4 * rows * cols));
// Iterate over each channel
for (int i = 1; i <= channels; ++i)
{
// Fetch the band
GDALRasterBand* band = dataset->GetRasterBand(i);
// Read the data
band->RasterIO(GF_Read, 0, 0, cols, rows, bandData[size_t(i - 1)].data(),
cols, rows, GDT_Byte, 0, 0);
}
for (size_t i = 0, j = 0; i < outputImage.size(); i += 4, j += 1)
{
outputImage[i] = bandData[0][j];
outputImage[i + 1] = bandData[1][j];
outputImage[i + 2] = bandData[2][j];
outputImage[i + 3] = bandData[3][j];
}
// Create the QImage (or even a QPixmap suitable for displaying teh image
QImage qtImage(outputImage.data(), cols, rows, QImage::Format_RGBA8888);
我使用 GDAL
读取一些图像文件并希望使用 Qt
显示它们。到目前为止,我设法为 GDALDataSet
中的每个 GDALRasterBand
创建了灰度 QImage
,但我不知道如何创建单个 RGB 图像。
这是我所做的:
#include <gdal_priv.h>
#include <QtGui\QImage>
int main(int argc, char *argv[])
{
GDALAllRegister();
GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen("path_to_some_image.tif", GA_ReadOnly));
int size_out = 200;
for (int i = 1; i <= 3; ++i)
{
GDALRasterBand* band = dataset->GetRasterBand(i);
std::vector<uchar> band_data(size_out * size_out);
band->RasterIO(GF_Read, 0, 0, size_out, size_out, band_data.data(), size_out, size_out, GDT_Byte, 0, 0);
QImage band_image(band_data.data(), size_out, size_out, QImage::Format_Grayscale8);
band_image.save(QString("C:\band_%1.png").arg(i));
}
return 0;
}
如何读取数据以便创建单个 RGB QImage
?
你快到了。第一项是 QImage 使用带有格式标志的缓冲区。因此,该格式标志需要匹配您从文件加载的图像,否则需要进行转换。下面的示例假设一个 4 通道图像。
QImage 格式标志文档:http://doc.qt.io/qt-5/qimage.html#Format-enum
下一个组成部分是 GDAL 的 RasterIO
方法分别处理每个波段,这意味着您必须分别交错像素,否则会失去逐个加载栅格带来的效率。
光栅IO:http://gdal.org/classGDALRasterBand.html#a30786c81246455321e96d73047b8edf1
我喜欢 OpenCV 的 merge
方法。只需为每个波段创建一个灰度图像并将它们 merge
放在一起。
OpenCV 合并:http://docs.opencv.org/3.0.0/d2/de8/group__core__array.html#ga61f2f2bde4a0a0154b2333ea504fab1d
例如,给定一个 RGBA GeoTiff,
// OpenCV Libraries
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// GDAL Libraries
#include <gdal.h>
// QT Libraries
#include <QtGui\QImage>
using namespace cv;
int main( int argc, char* argv[] )
{
// Initialize GDAL
GDALAllRegister();
// Load image
GDALDataset* dataset = GDALOpen("path_to_some_image.tif", GA_ReadOnly);
// Get raster image size
int rows = dataset->GetRasterYSize();
int cols = dataset->GetRasterXSize();
int channels = dataset->GetRasterCount();
// Create each separate image as grayscale
std::vector<cv::Mat> image_list(channels, cv::Mat( rows, cols, CV_8UC1 ));
cv::Mat output_image;
// Iterate over each channel
for (int i = 1; i <= channels; ++i)
{
// Fetch the band
GDALRasterBand* band = dataset->GetRasterBand(i);
// Read the data
band->RasterIO( GF_Read, 0, 0,
cols, rows,
image_list[i-1].data,
cols, rows,
GDT_Byte, 0, 0);
}
// Merge images
cv::merge( image_list, output_image );
// Create the QImage
QImage qt_image( band_data.data(),
cols,
rows,
QImage::Format_RGBA8888);
// Do some stuff with the image
return 0;
}
没有 OpenCV,使用 msmith81886 代码:
// Load image
GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen(tifFile.toLocal8Bit().data(), GA_ReadOnly));
// Get raster image size
int rows = dataset->GetRasterYSize();
int cols = dataset->GetRasterXSize();
int channels = dataset->GetRasterCount();
std::vector<std::vector<uchar>> bandData(channels);
for (auto& mat : bandData)
{
mat.resize(size_t(rows * cols));
}
std::vector<uchar> outputImage(size_t(4 * rows * cols));
// Iterate over each channel
for (int i = 1; i <= channels; ++i)
{
// Fetch the band
GDALRasterBand* band = dataset->GetRasterBand(i);
// Read the data
band->RasterIO(GF_Read, 0, 0, cols, rows, bandData[size_t(i - 1)].data(),
cols, rows, GDT_Byte, 0, 0);
}
for (size_t i = 0, j = 0; i < outputImage.size(); i += 4, j += 1)
{
outputImage[i] = bandData[0][j];
outputImage[i + 1] = bandData[1][j];
outputImage[i + 2] = bandData[2][j];
outputImage[i + 3] = bandData[3][j];
}
// Create the QImage (or even a QPixmap suitable for displaying teh image
QImage qtImage(outputImage.data(), cols, rows, QImage::Format_RGBA8888);