我尝试将pct2rgb.py
脚本重写为C#
(此脚本获取 8 位TIFF
图像并将其位深度更改为24-bit
)。当其输出存储在 HDD 上时,它可以工作。我想稍微改变一下脚本。它应该Dataset
在不将其存储在磁盘上的情况下即时返回。它工作......几乎......问题是返回Dataset
包含单色数据......我真的不知道为什么。可能是驱动程序从GTiff
变为MEM
(Driver 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.");
}
}