C# 如何使用GDAL进行拼接,裁剪图片

这段时间项目进行过程中,需要用到图片拼接和裁剪的功能,因为拼接出来的图片超大,BitMap有大小限制,就使用GDAL进行图像的拼接和裁剪,下面是一些用法。

1,需要引用GDAL 的dll包,这个可以在管理GuGet程序包里下载引用

图像拼接

  		/// <summary>
        /// 
        /// </summary>
        /// <param name="srcDs">小图数据</param>
        /// <param name="outDs">输出的大图数据</param>
        /// <param name="x">小图序号</param>
        /// <param name="startPix_X">起始X坐标</param>
        /// <param name="startPix_Y"><起始y坐标/param>
        private static void SaveBitMapBuffer(Dataset srcDs, Dataset outDs, int x, int startPix_X, int startPix_Y)
        {
            if (srcDs.RasterCount < 1)
            {
                return;
            }
            int width = srcDs.RasterXSize;
            int height = srcDs.RasterYSize;

            byte[] buf = new byte[width * height];

            srcDs.ReadRaster(0, 0, width, height, buf, width, height, 1, new int[] { 1 }, 0, 0, 0);
            outDs.WriteRaster(x * width - x * startPix_X, startPix_Y * x, width, height, buf, width, height, 1, new int[] { 1 }, 0, 0, 0);
        }
		//因为拼接成的图片不止一张,fileNameTable 的key是输出文件名,value是存放小图路径名的集合,
		//如果只是拼接一张图片的话可以直接传入一个输出文件名outFileName和list集合
  		public static void CombineTiles(Dictionary<string, List<string>> fileNameTable,int startPix_X, int startPix_Y )
        {
            
            if (fileNameTable.Count < 1)
            {
                return;
            }
            try
            {
                Gdal.AllRegister();
                foreach (KeyValuePair<string, List<string>> kvp in fileNameTable)
                {
                    string outFileName = kvp.Key;
                    List<string> fileNames = kvp.Value;
                    int imageWidth;
                    int imageHeight;
                    using (Dataset fristFileDs = Gdal.Open(kvp.Value[0], Access.GA_ReadOnly))
                    {
                     //合成图片的大小
                        imageWidth = fristFileDs.RasterXSize * fileNames.Count - (startPix_X* (fileNames.Count - 1));
                        imageHeight = fristFileDs.RasterYSize + (startPix_Y * (fileNames.Count - 1));
                    }
                   


                    Driver driver = Gdal.GetDriverByName("GTiff");
                    if (File.Exists(outFileName))
                    {
                        File.Delete(outFileName);
                    }
                    using (Dataset outDs = driver.Create(outFileName, imageWidth, imageHeight, 1, DataType.GDT_Byte, null))
                    {
                        for (int i = 0; i < fileNames.Count; i++)
                        {
                            string file = fileNames[i];
                            if (File.Exists(file))
                            {
                                using (Dataset srcDs = Gdal.Open(file, Access.GA_ReadOnly))
                                {
                                    if (srcDs != null)
                                    {
                                        SaveBitMapBuffer(srcDs, outDs, i, startPix_X, startPix_Y);
                                    }
                                }



                                //srcDs.Dispose();
                                //srcDs.CommitTransaction();
                            }
                            Console.WriteLine("写入图片数量:" + (i + 1) + ",剩余数量:" + (fileNames.Count - 1 - i));
                        }
                        //outDs.FlushCache();
                        // outDs.Dispose();
                    }
                }
            }
            catch 
            {
                throw;
            }
        }

裁图部分

// loopNum 循环次数
 static void TestCutPicture(String srcFileName, int startX, int startY, int dWidth, int dHeight,  int loopNum)
        {
            Gdal.AllRegister();
            Dataset srcDs;
            try
            {
                srcDs = Gdal.Open(srcFileName, Access.GA_ReadOnly);
            }
            catch 
            {
                Console.WriteLine("文件被其他线程访问!");
                return;
            }
            //Dataset srcDs = Gdal.Open(srcFileName, Access.GA_ReadOnly);
            DataType srcType = srcDs.GetRasterBand(1).DataType;
            int bandCount = srcDs.RasterCount;
            double[] adfGeoTransform = new double[6];
            srcDs.GetGeoTransform(adfGeoTransform);
            int[] dataArray = new int[dWidth * dHeight * bandCount];
            int[] bandArray = new int[1];
            bandArray[0] = 1;
            try
            {
                for (int i = 1; i <= loopNum; i++)
                {
                    SavePath = "";//保存路径 + 文件名

                    Driver drv = Gdal.GetDriverByName("GTIFF");
                    Dataset dstDs = drv.Create(SavePath.Replace(" ", ""), dWidth, dHeight, bandCount, srcType, null);

                    dstDs.SetGeoTransform(adfGeoTransform);
                    dstDs.SetProjection(srcDs.GetProjectionRef());
                    srcDs.ReadRaster(startX, startY, dWidth, dHeight, dataArray, dWidth, dHeight, bandCount, bandArray, 0, 0, 0);
                    dstDs.WriteRaster(0, 0, dWidth, dHeight, dataArray, dWidth, dHeight, bandCount, bandArray, 0, 0, 0);
                    dstDs.FlushCache();
                    dstDs.Dispose();
                    startX = (int)(startX + dWidth );
                    Console.WriteLine(SavePath+" 创建成功!");
                }
            }
            catch (Exception ex)
            {

                return;
            }

            srcDs.Dispose();
        }

OK,结束,因为代码是直接从项目上拷下来的,也许有一些地方不适用,欢迎留言评论,我看到会回复的。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小小陆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值