19,464
社区成员
发帖
与我相关
我的任务
分享
//坐标搞错了,应该是这样
pSrcBand->RasterIO(GF_Read, j*width, i*height, width, height, pBlock, width, height, GDT_Byte, 0, 0);
//这是我用GDAL写的拆分tiff函数,运行后(2行 x 1列)有错误,size设的不对,tif大小为
//2470 x 1933 x 3
//提示: ERROR 5: Access window out of range in RasterIO(). Requested
//(2470,0) of size 2470x966 on range of 2470x1933
//请帮我看下哪不对?谢谢
void SplitTiff(char * fname, int row, int col, char * outfolder)
{
//Open file
GDALDataset * pSrcDS = NULL;
GDALDriver *pDriver = NULL;
pDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
if(!pDriver)
return;
pSrcDS = (GDALDataset*)GDALOpen(fname, GA_ReadOnly);
if(!pSrcDS)
return;
int XSize,YSize;
XSize = pSrcDS->GetRasterXSize();
YSize = pSrcDS->GetRasterYSize();
if((XSize<=0) || (YSize<=0))
{
delete pSrcDS;
return;
}
int i,j;
int width,height;
char destname[256];
GDALDataset * pDestDS;
char **papszOptions = NULL;
GDALRasterBand *pSrcBand,*pDestBand;
width = (int)(XSize/col);
height = (int)(YSize/row);
for (i=0; i<row; ++i)
{
for (j=0; j<col; ++j)
{
//Create file
sprintf(destname, "%s\\%d%d.tif", outfolder, i, j);
pDestDS = pDriver->Create(destname, width, height, 3, GDT_Byte, papszOptions);
if (pDestDS)
{
byte * pBlock = (byte*) CPLMalloc(width*height*sizeof(byte));
for (int band=0; band<3; band++)
{
//Read data
pSrcBand = pSrcDS->GetRasterBand(band+1);
pSrcBand->RasterIO(GF_Read, i*width, j*height, width, height, pBlock, width, height, GDT_Byte, 0, 0);
//Write data
pDestBand = pDestDS->GetRasterBand(band+1);
pDestBand->RasterIO(GF_Write, 0, 0, width, height, pBlock, width, height, GDT_Byte, 0, 0);
}
CPLFree(pBlock);
delete pDestDS;
}
}
}
//Close
delete pSrcBand;
}
for (int band=0; band<3; band++)
{
//Read data
pSrcBand = pSrcDS->GetRasterBand(band+1);
pSrcBand->RasterIO(GF_Read, i*width, j*height, width, height, pBlock, width, height, GDT_Byte, 0, 0);// 这里不能是i*weidth 而是0 .你不是切成2行一列吗?
//Write data
pDestBand = pDestDS->GetRasterBand(band+1);
pDestBand->RasterIO(GF_Write, 0, 0, width, height, pBlock, width, height, GDT_Byte, 0, 0);
}
// 先假设你不管通过libtiff的哪个函数把数据读到pSrc里面了。并且是8位的。
// 接着你就可以通过下面的函数切割图像。 我对libtiff不熟悉,一直在用GDAL
// 一个很牛逼的库。google earth就是用它写的。虽然也通过读取一个区域的
// 函数。RasterIO(pszFilename,regionbeginX, reguionbeginY, regionendX, regionendY, byte*
// Buf,nBufX,nBufY,.... )
// 但是效率都不如自己写的高。建议你还是先读数据出来。在切割,不要通过库提供的函数。
// 下面是切割的程序,如果行的话。再给你提供合并的程序。
int CutImage(byte *pSrc, int width, int height,int nX, int nY )
{
// 注意如果原图的width*height != 原图数据的bytes
// 那么就说明每行有补零,补到4字节整数宽度
int residual = (width%4)%4;
int num = nY * nX; // nY*nX 是要切割的子图像数目。
int subDim= width/nX; // 边角料的宽度
CSize *pSubSize = new CSize[num]; // 存子图的数据 CSize是一个结构体 2个元素 cx 和cy
// CRect *pSubrt = new CRect[num]; // 存子图的尺寸
// 计算每个子图像的长和宽
for ( int i=0; i<nY; i++)
{
for ( int j=0; j<nX; j++)
{
if (i == nY )// 边角料的宽度可能 != subDim
{
pSubSize[i*nX+j].cy = height - subDim * (nY-1);
}
else
{
pSubSize[i*nX+j].cy = subDim;
}
if (j == nX )
{
pSubSize[i*nX+j].cx = width - subDim*(nX-1);
}
else
{
pSubSize[i*nX+j].cx = subDim;
}
}
}
// 存子图像数据的数组
BYTE **pSub = new BYTE * [num];
for (int s=0; s<num; s++)
{
pSub[s] = new BYTE[pSubSize[s].cx * pSubSize[s].cy ] ;
}
// 切割原图,存到各个子图像数组中去。
int nrow=0;
int ncol=0;
for (int k=0; k<num; k++)
{
nrow = ( k/nX ) * subDim;
ncol = ( k%nY ) * subDim;
for ( i=0; i< pSubSize[k].cy; i++ )
{
for (int j=0; j<pSubSize[k].cx; j++ )
{
pSub[k][i* (pSubSize[k].cx) +j] =
pSrc[(nrow +i) *(width+residual) + ncol +j ];
}
}
}
}