使用 LibTiff 写入 TIFF 图像的 RGB 值
Writing RGB values of the TIFF image with LibTiff
我正在尝试创建 TIFF 图像的颜色图(不确定正确的术语)- 来自 this kind of image to such,据我所知,我需要相应地修改所有 RGB 值。
我在使用 Libtiff.net 修改现有图像时遇到问题,并且有示例说明如何 读取 图像中的 RGBA 值 (link), but no examples on how to write them into the image. (single one缺少实际将值写入栅格)。
也许有人做过类似的事情或者有使用这个库处理 TIFF 图像中的 RGB 的经验。
库不提供改变现有图像像素的方法。
推荐的工作流程是:阅读 pixels/samples -> 根据需要编辑它们 -> 使用编辑后的样本创建新图像。请注意,不需要将样本转换为 RGB。
您可以在库代码库的Samples文件夹中找到相关示例代码。您可能想从这些开始:
如果将来有人偶然发现同样的东西,我就是这样实现的。
- 我通过保留像素格式的默认 TiffBitmapDecoder 读取图像。
- 已将图像数据检索到 ushort[] 数组中。
- 根据 ushort 数组中的值计算了新的 RGB 并创建了一个新图像,不是原始的 48 位,而是 16 位,这对我的目的来说很好。
代码如下所示:
using var inputImageStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = new TiffBitmapDecoder(inputImageStream, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
int bytesPerPixel = (bitmapSource.Format.BitsPerPixel + 7) / 8;
int ushortStride = bitmapSource.PixelWidth * bytesPerPixel;
ushort[] pixelData = new ushort[(bitmapSource.PixelHeight * ushortStride) / 2];
bitmapSource.CopyPixels(pixelData, ushortStride, 0);
var writeableBitmap = new WriteableBitmap(
bitmapSource.PixelWidth,
bitmapSource.PixelHeight,
bitmapSource.DpiX, bitmapSource.DpiY,
bitmapSource.Format,
bitmapSource.Palette);
var channelValues = RetrieveDataAccordingToChannel(pixelData, selectedChannel);
在 RetrieveDataAccordingToChannel 中,我读取了每个第 N 个值 - 取决于所选的颜色通道。
/// <summary>
/// This method retrieves every 3rd element starting with specific index. Index depends on color channel.
/// Pixel data looks like a 1D array, where every 3 elements is a pixel color data -
/// e.g. [1, 2, 3, 4, 5, 6...] - 1 and 4 are red channels of first and second pixel,
/// 2 and 5 is green values of first and second pixel, and 3 and 6 is blue values
/// of first and second pixels respectively.
/// </summary>
public ushort[] RetrieveDataAccordingToChannel(ushort[] pixelData, ColorChannel colorChannel)
{
int startElement = 0;
switch (colorChannel)
{
case ColorChannel.Red:
startElement = 0;
break;
case ColorChannel.Green:
startElement = 1;
break;
case ColorChannel.Blue:
startElement = 2;
break;
}
var outputArray = new List<ushort>();
for (int i = startElement; i < pixelData.Length; i += 3)
{
var element = pixelData[i];
outputArray.Add(element);
}
return outputArray.ToArray();
}
之后我创建了一个新的位图,我在其中写入处理过的像素。
将值处理成新的颜色图如下所示(我从 https://github.com/ar1st0crat/SciColorMaps 获取颜色图):
var colormap = new ColorMap("Jet",
min, // Mininimum value in the channel data
max); // Maximum value in the channel data.
...
byte[] color = colormap[channelDataValue];
bitmap.SetPixel(x, y, Color.FromArgb(color[0], color[1], color[2]));
我正在尝试创建 TIFF 图像的颜色图(不确定正确的术语)- 来自 this kind of image to such,据我所知,我需要相应地修改所有 RGB 值。
我在使用 Libtiff.net 修改现有图像时遇到问题,并且有示例说明如何 读取 图像中的 RGBA 值 (link), but no examples on how to write them into the image. (single one缺少实际将值写入栅格)。 也许有人做过类似的事情或者有使用这个库处理 TIFF 图像中的 RGB 的经验。
库不提供改变现有图像像素的方法。
推荐的工作流程是:阅读 pixels/samples -> 根据需要编辑它们 -> 使用编辑后的样本创建新图像。请注意,不需要将样本转换为 RGB。
您可以在库代码库的Samples文件夹中找到相关示例代码。您可能想从这些开始:
如果将来有人偶然发现同样的东西,我就是这样实现的。
- 我通过保留像素格式的默认 TiffBitmapDecoder 读取图像。
- 已将图像数据检索到 ushort[] 数组中。
- 根据 ushort 数组中的值计算了新的 RGB 并创建了一个新图像,不是原始的 48 位,而是 16 位,这对我的目的来说很好。
代码如下所示:
using var inputImageStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = new TiffBitmapDecoder(inputImageStream, BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
int bytesPerPixel = (bitmapSource.Format.BitsPerPixel + 7) / 8;
int ushortStride = bitmapSource.PixelWidth * bytesPerPixel;
ushort[] pixelData = new ushort[(bitmapSource.PixelHeight * ushortStride) / 2];
bitmapSource.CopyPixels(pixelData, ushortStride, 0);
var writeableBitmap = new WriteableBitmap(
bitmapSource.PixelWidth,
bitmapSource.PixelHeight,
bitmapSource.DpiX, bitmapSource.DpiY,
bitmapSource.Format,
bitmapSource.Palette);
var channelValues = RetrieveDataAccordingToChannel(pixelData, selectedChannel);
在 RetrieveDataAccordingToChannel 中,我读取了每个第 N 个值 - 取决于所选的颜色通道。
/// <summary>
/// This method retrieves every 3rd element starting with specific index. Index depends on color channel.
/// Pixel data looks like a 1D array, where every 3 elements is a pixel color data -
/// e.g. [1, 2, 3, 4, 5, 6...] - 1 and 4 are red channels of first and second pixel,
/// 2 and 5 is green values of first and second pixel, and 3 and 6 is blue values
/// of first and second pixels respectively.
/// </summary>
public ushort[] RetrieveDataAccordingToChannel(ushort[] pixelData, ColorChannel colorChannel)
{
int startElement = 0;
switch (colorChannel)
{
case ColorChannel.Red:
startElement = 0;
break;
case ColorChannel.Green:
startElement = 1;
break;
case ColorChannel.Blue:
startElement = 2;
break;
}
var outputArray = new List<ushort>();
for (int i = startElement; i < pixelData.Length; i += 3)
{
var element = pixelData[i];
outputArray.Add(element);
}
return outputArray.ToArray();
}
之后我创建了一个新的位图,我在其中写入处理过的像素。
将值处理成新的颜色图如下所示(我从 https://github.com/ar1st0crat/SciColorMaps 获取颜色图):
var colormap = new ColorMap("Jet",
min, // Mininimum value in the channel data
max); // Maximum value in the channel data.
...
byte[] color = colormap[channelDataValue];
bitmap.SetPixel(x, y, Color.FromArgb(color[0], color[1], color[2]));