GDAL pct2rgb.py返回单色数据

2024-05-16 01:14:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试将pct2rgb.py脚本重写为C#(这个脚本获得8位TIFF图像,并将其位深度改为24-bit)。当它的输出存储在硬盘上时,它就工作了。我想稍微修改一下剧本。它应该动态返回Dataset,不需要将其存储在磁盘上。它起作用了。。。几乎。。。问题是返回的Dataset包含单色数据。。。我真的不知道为什么。可能是由驱动程序从GTiff更改为MEMDriver gTiffDriver = Gdal.GetDriverByName("MEM");)引起的。但我不知道如何使用GTiff驱动程序而不将数据存储在硬盘上。。。在

这是我的课:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using OSGeo.GDAL;
using OSGeo.OGR;
using OSGeo.OSR;
using Driver = OSGeo.GDAL.Driver;
using Encoder = System.Drawing.Imaging.Encoder;
using PixelFormat = System.Drawing.Imaging.PixelFormat;

namespace RasterLoader
{
    public class TiffConverter
    {
        private string _format = "GTiff";
        private string _srcFileName = null;
        private int _outBands = 3;
        private int _bandNumber = 1;
        private string[] _args;

        public TiffConverter(string[] args)
        {
            _args = args;
        }

        public Dataset Convert8To24Bit()
        {
            Gdal.AllRegister();

            string[] argv = Gdal.GeneralCmdLineProcessor(_args, 0);

            int i = 1;
            while (i < argv.Count())
            {
                string arg = argv.ElementAt(i);
                switch (arg)
                {
                    case "-of":
                        i++;
                        _format = argv[i];
                        break;
                    case "-b":
                        i++;
                        _bandNumber = int.Parse(argv[i]);
                        break;
                    case "-rgba":
                        _outBands = 4;
                        break;
                    default:
                        if (string.IsNullOrEmpty(_srcFileName))
                        {
                            _srcFileName = argv[i];
                        }
                        else
                        {
                            Usage();
                        }
                        break;
                }
                i++;
            }

            string tmpFileName = _srcFileName + ".bak";

            // open source file
            Dataset srcDS = Gdal.Open(_srcFileName, Access.GA_ReadOnly);
            if (srcDS == null)
            {
                throw new Exception("Unable to open " + _srcFileName + ".");
            }

            Band srcBand = srcDS.GetRasterBand(_bandNumber);

            // ensure we recognise the driver
            Driver dstDriver = Gdal.GetDriverByName(_format);
            if (dstDriver == null)
            {
                throw new Exception("\"" + _format + "\" not registered.");
            }

            // build color table
            int[][] lookup = new int[4][];
            lookup[0] = Enumerable.Range(0, 256).ToArray();
            lookup[1] = Enumerable.Range(0, 256).ToArray();
            lookup[2] = Enumerable.Range(0, 256).ToArray();
            lookup[3] = new int[256];

            for (i = 0; i < 256; i++)
            {
                lookup[3][i] = 255;
            }

            ColorTable ct = srcBand.GetRasterColorTable();

            if (ct != null)
            {
                for (i = 0; i < Math.Min(256, ct.GetCount()); i++)
                {
                    ColorEntry entry = ct.GetColorEntry(i);
                    for (int j = 0; j < 4; j++)
                    {
                        switch (j)
                        {
                            case 0:
                                lookup[j][i] = entry.c1;
                                break;
                            case 1:
                                lookup[j][i] = entry.c2;
                                break;
                            case 2:
                                lookup[j][i] = entry.c3;
                                break;
                            case 3:
                                lookup[j][i] = entry.c4;
                                break;
                        }
                    }
                }
            }

            // create the working file
            string tifFileName = string.Empty;
            if (_format.Equals("GTiff", StringComparison.OrdinalIgnoreCase))
            {
                tifFileName = tmpFileName;
            }
            else
            {
                tifFileName = Path.Combine(Directory.GetParent(tmpFileName).Name, "temp.gif");
            }

//            Driver gTiffDriver = Gdal.GetDriverByName("GTiff");
            Driver gTiffDriver = Gdal.GetDriverByName("MEM");

            Dataset tifDS = gTiffDriver.Create(tifFileName, srcDS.RasterXSize, srcDS.RasterYSize, _outBands, DataType.GDT_Byte,
                                               new string[] {});

            // we should copy projection information and so forth at this point
            tifDS.SetProjection(srcDS.GetProjection());
            double[] geotransform = new double[6];
            srcDS.GetGeoTransform(geotransform);
            tifDS.SetGeoTransform(geotransform);

            if (srcDS.GetGCPCount() > 0)
            {
                tifDS.SetGCPs(srcDS.GetGCPs(), srcDS.GetGCPProjection());
            }

            // do the processing one scanline at a time
            for (int iY = 0; iY < srcDS.RasterYSize; iY++)
            {
                byte[] srcData = new byte[srcDS.RasterXSize*1];
                srcBand.ReadRaster(0, iY, srcDS.RasterXSize, 1, srcData, srcDS.RasterXSize, 1, 0, 0);

                for (int iBand = 0; iBand < _outBands; iBand++)
                {
                    int[] bandLookup = lookup[iBand];

                    int[] dstData = new int[srcData.Count()];
                    for (int index = 0; index < srcData.Count(); index++)
                    {
                        byte b = srcData[index];
                        dstData[index] = bandLookup[b];
                    }

                    tifDS.GetRasterBand(iBand + 1).WriteRaster(0, iY, srcDS.RasterXSize, 1, dstData,
                                                               srcDS.RasterXSize, 1, 0, 0);
                }
            }

            return tifDS;
        }

        private void Usage()
        {
            Console.WriteLine("Usage: pct2rgb.py [-of format] [-b <band>] [-rgba] source_file dest_file");
            throw new Exception("Bad arguments.");
        }
}

Tags: formatnewstringdriverprivatelookupsystemint
1条回答
网友
1楼 · 发布于 2024-05-16 01:14:23

好吧。我找到了解决办法。我的问题是我试图转换所有的文件(即使是一个好的格式)。那么ct变量(ColorTable)是null。在

解决方案:

if (ct != null)
{
// same code here
}
else
{
   return srcDS;
}

相关问题 更多 >