本处使用DataSet的ReadRaster和WriteRaster方法实现水平镜像
private void btnOzil_Click(object sender, EventArgs e)
{
string openFileName = "";
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
openFileName = ofd.FileName;
}
Gdal.AllRegister();
//jpg格式不支持update
Dataset srcDs = Gdal.Open(openFileName, Access.GA_ReadOnly);
DataType srcType = srcDs.GetRasterBand(1).DataType;//byte类型
int bandCount = srcDs.RasterCount;
int srcWidth = srcDs.RasterXSize;
int srcHeight = srcDs.RasterYSize;
Debug.WriteLine("原始影像数据类型是:{0}", srcType);
Debug.WriteLine("原始影像的列数:{0}", srcWidth);
Debug.WriteLine("原始影像的行数:{0}", srcHeight);
int[] bandArray = new int[bandCount];
for (int i = 0; i < bandCount; i++)
{
bandArray[i] = i + 1;
}
//注意,JPG没有实现Create方法来创建
//Dataset dstDs= drv.Create(dstFileName,srcWidth,srcHeight,bandCount,DataType.GDT_Byte,null);
//首先创建一个内存的驱动
string strMemory=@"E:\tempMemory.jpg";
Driver dryMemory = Gdal.GetDriverByName("MEM");
Dataset dsMemory = dryMemory.Create(strMemory, srcWidth, srcHeight,bandCount, DataType.GDT_Byte, null);
if (srcType == DataType.GDT_Byte)
{
int[] dataArray = new int[srcWidth * srcHeight * bandCount];
//ReadRaster最后三个参数全是0,默认按照波段顺序存储
srcDs.ReadRaster(0, 0, srcWidth, srcHeight, dataArray, srcWidth, srcHeight, bandCount, bandArray, 0, 0, 0);
/***********水平镜像实现**************/
//输出改变前的第200行
//Debug.WriteLine("改变前");
//for(int ii=0;ii<srcWidth;++ii)
//{
// Debug.Write(dataArray[200*srcWidth+ii].ToString() + " ");
//}
//Debug.WriteLine("改变后");
/***********镜像方法1——通过************/
int bandTemp,temp;
for (int b = 0; b < bandCount; ++b )//循环3个波段
{
// srcWidth * srcWidth*0 到 srcWidth * srcWidth*1-1 ————R波段
// srcWidth * srcWidth*1 到 srcWidth * srcWidth*2-1 ————G波段
// srcWidth * srcWidth*2 到 srcWidth * srcWidth*3-1 ————R波段
bandTemp = b * srcWidth * srcHeight;
for (int i = 0; i < srcHeight; i++)
{
for (int j = 0; j < srcWidth / 2; j++)
{
temp = dataArray[bandTemp + i * srcWidth + j];
dataArray[bandTemp + i * srcWidth + j] = dataArray[bandTemp + i * srcWidth + (srcWidth - 1 - j)];
dataArray[bandTemp + i * srcWidth + (srcWidth - 1 - j)] = temp;
}
}
}
/***********镜像方法1************/
/***********镜像方法2:这样和镜像方法3一样,是将图片按照斜上45度进行了镜像************/
//因为没有安装每个波段,每一行数据进行交换,而是将整个数组进行了反转
//int[] newArray = new int[srcWidth * srcHeight * bandCount];
//for (int mm = 0; mm <= srcWidth * srcHeight - 1; ++mm)
//{
// newArray[mm] = dataArray[srcWidth * srcHeight - 1 - mm];
//}
//for (int nn = srcWidth * srcHeight; nn <= srcWidth * srcHeight * 2 - 1; ++nn)
//{
// newArray[nn] = dataArray[srcWidth * srcHeight * 2 - 1 - nn];
//}
//for (int mn = srcWidth * srcHeight * 2; mn < srcWidth * srcHeight * 3 - 1; ++mn)
//{
// newArray[mn] = dataArray[srcWidth * srcHeight * 3 - 1 - mn];
//}
/***********镜像方法2************/
/***********镜像方法2改进——未完成************/
//int tempTwo;
//for (int mm = 0; mm <= srcWidth * srcHeight*3 - 1; ++mm)
//{
// if(mm<=srcHeight*srcWidth-1)
// {
// for (int ix = 0; ix < srcHeight; ++ix)
// {
// for (int iix = 0; iix < srcWidth / 2; ++iix)
// {
// tempTwo = dataArray[ix * srcWidth + iix];
// dataArray[ix * srcWidth + iix] = dataArray[ix * srcWidth + srcWidth - 1 - iix];
// dataArray[ix * srcWidth + srcWidth - 1 - iix] = tempTwo;
// }
// }
// }
// else if(mm<=srcWidth*srcHeight*2-1)
// {
// int nn = srcHeight * srcWidth;
// for (int iy = 0; iy < srcHeight; ++iy)
// {
// for (int iiy = 0; iiy < srcWidth / 2; ++iiy)
// {
// tempTwo = dataArray[nn + iy * srcWidth + iiy];
// dataArray[nn + iy * srcWidth + iiy] = dataArray[nn + iy * srcWidth + srcWidth - 1 - iiy];
// dataArray[nn + iy * srcWidth + srcWidth - 1 - iiy] = tempTwo;
// }
// }
// }
// else if(mm<=srcWidth*srcHeight*3-1)//最后一个跳出for
// {
// int mn = srcWidth * srcHeight * 2;
// for (int iz = 0; iz < srcHeight; ++iz)
// {
// for (int iiz = 0; iiz < srcWidth / 2; ++iiz)
// {
// tempTwo = dataArray[mn + iz * srcWidth + iiz];
// dataArray[mn + iz * srcWidth + iiz] = dataArray[mn + iz * srcWidth + srcWidth - 1 - iiz];
// dataArray[mn + iz * srcWidth + srcWidth - 1 - iiz] = tempTwo;
// }
// }
// }
//}
//for (int nn = srcWidth * srcHeight; nn <= srcWidth * srcHeight * 2 - 1; ++nn)
//{
// for (int iy = 0; iy < srcHeight; ++iy)
// {
// for (int iiy = 0; iiy < srcWidth / 2; ++iiy)
// {
// tempTwo = dataArray[nn+iy * srcWidth + iiy];
// dataArray[nn + iy * srcWidth + iiy] = dataArray[nn + iy * srcWidth + srcWidth - 1 - iiy];
// dataArray[nn + iy * srcWidth + srcWidth - 1 - iiy] = tempTwo;
// }
// }
//}
//for (int mn = srcWidth * srcHeight * 2; mn < srcWidth * srcHeight * 3 - 1; ++mn)
//{
// for (int iz = 0; iz < srcHeight; ++iz)
// {
// for (int iiz = 0; iiz < srcWidth / 2; ++iiz)
// {
// tempTwo = dataArray[mn+iz * srcWidth + iiz];
// dataArray[mn + iz * srcWidth + iiz] = dataArray[mn + iz * srcWidth + srcWidth - 1 - iiz];
// dataArray[mn + iz * srcWidth + srcWidth - 1 - iiz] = tempTwo;
// }
// }
//}
/***********镜像方法2改进************/
/***********镜像方法3************/
Array.Reverse(dataArray);
/***********镜像方法3************/
//输出改变后的第200行
//for (int jj = 0; jj <srcWidth; ++jj)
//{
// Debug.Write(dataArray[200 * srcWidth + jj].ToString() + " ");
//}
//将更新数值的数据重新写入图像
//镜像方法1
dsMemory.WriteRaster(0, 0, srcWidth, srcHeight, dataArray, srcWidth, srcHeight, bandCount, bandArray, 0, 0, 0);
//镜像方法2
//dsMemory.WriteRaster(0, 0, srcWidth, srcHeight, newArray, srcWidth, srcHeight, bandCount, bandArray, 0, 0, 0);
//镜像方法2改进
//dsMemory.WriteRaster(0, 0, srcWidth, srcHeight, dataArray, srcWidth, srcHeight, bandCount, bandArray, 0, 0, 0);
//镜像方法3
//int[] newBandArray = new int[] { 3,2,1};
//dsMemory.WriteRaster(0, 0, srcWidth, srcHeight, dataArray, srcWidth, srcHeight, bandCount, newBandArray, 0, 0, 0);
dsMemory.FlushCache();
}
Driver drvJPG = Gdal.GetDriverByName("JPEG");
string dstFileName = @"E:\3result_ozil1.jpg";
drvJPG.CreateCopy(dstFileName, dsMemory, 1, null, null, null);
//最后释放资源
srcDs.Dispose();
dsMemory.Dispose();
MessageBox.Show("水平镜像:success");
}
高圆圆原图 :
高圆圆镜像效果:
厄齐尔原图:
厄齐尔镜像效果:
注意,若使用未改进的镜像方法2和方法3,则会实现沿着45度角镜像,因为没有安装每个波段,每一行数据进行交换,而是将整个数组进行了反转:
效果分别是:
和