/*使用gdal将图像进行重采样,然后按照指定的格式输出 * 运行此程序需要安装gdal,目前知道可以处理.tif、.img。生成.jpeg图像 * 生成.so命令:g++ -fpic -shared -o libxxx.so main.cpp -lgdal * main.cpp * * Created on: 2013-1-15 * Author: he_fa */#include "gdal_priv.h"#include "cpl_conv.h"#include <stdio.h>#include <stdlib.h>#include <string.h>/** *将Dataset转换成图像 *@param szPath 目标文件 *@param poDataset 源Dataset *@param pszFormat 目标文件的格式,必须得和目标文件的后缀名一样 *@return 1:成功 0:失败 */int MEM_to_File(const char *szPath, GDALDataset *poDataset, char *pszFormat = "JPEG"){ if(NULL == szPath) { printf("输出路径不能为空!\n"); return 0; } GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //设置支持中文路径 GDALDriver *pJPGDriver; pJPGDriver = GetGDALDriverManager()->GetDriverByName("JPEG"); if(NULL == pJPGDriver) { printf("不能创建指定类型的文件,请检查该文件类型GDAL是否支持创建 \n"); return 0; } GDALDataset *pJPGDataset; pJPGDataset = pJPGDriver->CreateCopy(szPath, poDataset, FALSE, NULL, NULL, NULL); GDALClose((GDALDatasetH)pJPGDataset); return 1;}/** * 将图像转换成指定大小的MEM的Dataset, * @param file_path 图像的路径 * @param MEM_Xsize MEM图像的宽 * @param MEM_Ysize MEM图像的高 * @parma pDataset 用于保存结果 * @return 1:成功 0:失败 */int file_to_MEM(const char *file_path, int MEM_Xsize, int MEM_Ysize, GDALDataset **pDataset){ GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //设置支持中文路径 GDALDataset *poDataset= (GDALDataset *)GDALOpen(file_path, GA_ReadOnly); if(NULL == poDataset) { printf("图像打开失败,路径可能有误!\n"); return 0; } //获取输入图像的基本信息 int band_count = poDataset->GetRasterCount(); int nXSize = poDataset->GetRasterXSize(); int nYSize = poDataset->GetRasterYSize(); //获取MEM的驱动和数据集 GDALDriver *pMEMDriver = GetGDALDriverManager()->GetDriverByName("MEM"); if(NULL == pMEMDriver) { printf("MEMDriver创建失败!\n"); GDALClose((GDALDatasetH)poDataset); return 0; } //gdal无法处理GDT_Float32,只能处理8位或12位,所以写成GDT_Byte GDALDataset *MEMDataset = pMEMDriver->Create("", MEM_Xsize, MEM_Ysize, band_count, GDT_Byte, NULL); if(NULL == MEMDataset) { printf("MEM的Dataset创建失败!\n"); return 0; } //两个辅助数组,用于读取File的数据和写入MEM的Dataset的数据 float *pafScanline = (float *)CPLMalloc(sizeof(float *) * MEM_Xsize); unsigned char *array = (unsigned char*)CPLMalloc(sizeof(unsigned char*) * MEM_Xsize); if(NULL == pafScanline || NULL == array) { printf("辅助数组内存分配失败!\n"); return 0; } //用于重采样,控制读取原图像的哪一行 float Ysteps = 1.0f * nYSize / MEM_Ysize; int i_count; for(i_count = 1; i_count <= band_count; ++ i_count) { GDALRasterBand *psrcBand = poDataset->GetRasterBand(i_count); GDALRasterBand *pdstBand = MEMDataset->GetRasterBand(i_count); //用于获取图像像素的最值 float max = -999999, min = 999999; float file_line; int MEM_line; //用于控制将数组的值写入MEM的Dataset for(file_line = 0, MEM_line = 0; file_line < nYSize && MEM_line < MEM_Ysize; file_line += Ysteps, ++ MEM_line) { psrcBand->RasterIO(GF_Read, 0, (int)file_line, nXSize, 1, pafScanline, MEM_Xsize, 1, GDT_Float32, 0, 0); //对采样得到的数组求最值 int i; for(i = 0; i < MEM_Xsize; ++ i) { max = max > pafScanline[i] ? max : pafScanline[i]; min = min < pafScanline[i] ? min : pafScanline[i]; } //将float数组中的数值转换成unsigned char, 将图像的像素值进行拉伸成0~255 for(i = 0; i < MEM_Xsize; ++ i) { array[i] = (unsigned char)((pafScanline[i] - min) * 255 / (max - min + 1)); } //将数组中的数据写入MEM的Dataset pdstBand->RasterIO(GF_Write, 0, MEM_line, MEM_Xsize, 1, array, MEM_Xsize, 1, GDT_Byte, 0, 0); } } *pDataset = MEMDataset; //MEMDataset不能关闭 GDALClose((GDALDatasetH)poDataset); free(pafScanline); free(array); return 1;}int main(void){ GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //设置支持中文路径 GDALDataset *pDataset; if(0 == file_to_MEM("/home/he_fa/project/test.img", 1000, 1000, &pDataset) ) { return 0; } if(0 == MEM_to_File("/home/he_fa/project/result.jpg", pDataset, "jpg") ) { return 0; } GDALClose((GDALDatasetH)pDataset); return 1;}//extern "C" int run(char *inpath, char *outpath)//{// GDALAllRegister();// CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO"); //设置支持中文路径// GDALDataset *pDataset;// if(0 == file_to_MEM(inpath, 1000, 1000, &pDataset))// {// return 0;// }// if(0 == MEM_to_File(outpath, pDataset, "jpg"))// {// return 0;// }// GDALClose((GDALDatasetH)pDataset);// return 1;//}