朋友!我需要将一组小图像作为表格放置在Tiff文件中。
文件在最终文件中应如何显示: 我为此使用LibTIFF库。 告诉我如何实施?我用C#实现了解决方案,但是语言无关紧要,因为重写解决方案不是问题。
var Row = 10;
var Column = 10;
var PIXEL_WIDTH = 8810;
var PIXEL_HEIGHT = 11810;
//Each small image has a resolution of 881x1181
using (Tiff tiff = Tiff.Open("big.tif", "w"))
{
tiff.SetField(TiffTag.IMAGEWIDTH, PIXEL_WIDTH);
tiff.SetField(TiffTag.IMAGELENGTH, PIXEL_HEIGHT);
tiff.SetField(TiffTag.COMPRESSION, Compression.LZW);
tiff.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);
tiff.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
tiff.SetField(TiffTag.ROWSPERSTRIP, PIXEL_HEIGHT);
tiff.SetField(TiffTag.XRESOLUTION, 120);
tiff.SetField(TiffTag.YRESOLUTION, 120);
tiff.SetField(TiffTag.BITSPERSAMPLE, 8);
tiff.SetField(TiffTag.SAMPLESPERPIXEL, 3);
tiff.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
int tileC = 0;
for (int row = 0; row < Row; row++)
{
for (int col = 0; col < Column; col++)
{
Bitmap bitmap = new Bitmap($"{row}x{col}.png");
byte[] raster = getImageRasterBytes(bitmap, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
tiff.WriteEncodedStrip(tileC++, raster, raster.Length);
}
}
tiff.WriteDirectory();
}
谢谢!
答案 0 :(得分:0)
首先让我们把问题的TIFF部分放在一边。主要问题是,您需要弄清楚如何组织内存中的像素数据,然后才能将最终图像保存为任何图像类型。
我将提供自己的简单示例来说明如何组织像素数据。
假设我们要在3x3的表格中合并9张图像。
每个图像将为3x3像素和8位单声道(1通道)。
这使得该示例很好用,简单,每个图像有9个字节,每个图像的步幅为每行3个字节。
合并后的图像最终将为9x9像素,总共81个字节。
这些图像分别命名为A,B,C ... I
A0
是A像素数据的字节0,A1
是字节1,依此类推...
这些图像将像这样在3x3的表格中组织起来:
ABC
DEF
GHI
然后,最终数据布局应如下所示:
byte[] pixelData = [
A0,A1,A2,B0,B1,B2,C0,C1,C2,
A3,A4,A5,B3,B4,B5,C3,C4,C5,
A6,A7,A8,B6,B7,B8,C6,C7,C8,
D0,D1,D2,E0,E1,E2,F0,F1,F2,
D3,D4,D5,E3,E4,E5,F3,F4,F5,
D6,D7,D8,E6,E7,E8,F6,F7,F8,
G0,G1,G2,H0,H1,H2,I0,I1,I2,
G3,G4,G5,H3,H4,H5,I3,I4,I5,
G6,G7,G8,H6,H7,H8,I6,I7,I8
];
然后可以将上面的像素阵列写入所需的任何图像文件。包括TIFF。
在上面的数组中的通知:
当您从索引0到80遍历该数组时,您将在同一行的三张图像之间来回跳转,直到完全到达下一行为止,在同一行中访问该行的下三张图像模式。
要实现这样的内存布局,可以使用几种方法。
Graphics
中的System.Drawing
类可用于制作一个大的空白图像,然后您可以在任意位置将每个子图像绘制到该大图像中。 (这是获得所需东西的最简单方法,但是可能很慢。)// For the example I have given above, in pseudo C# code
int composite_stride = image_stride * 3; // 3 is the number of images per row
int composite_size = composite_stride * image_height * 3 // 3 is the number of images per column
byte[] composite_pixels = new byte[composite_size];
// Loop over each image you want to combine
// We need some way to know which row/column the image is from, let that be assigned to table_row and table_col
// We are also assuming all images have the same width and height
foreach (image in table)
{
int comp_x = table_col * image.width;
int comp_y = table_row * image.height;
for (int y=0; y<image.height; y++)
{
// Calculate the array index that the current row starts at
int comp_row_start = comp_y * composite_stride;
for (int x=0; x<image.width; x++)
{
// Calculate the array index in the composite image to write to, and the source image index to copy from
int comp_index = comp_row_start + ((comp_x + x) * image.bytes_per_pixel);
int img_index = (y * image.stride) + (x * image.bytes_per_pixel);
composite_pixels[pixel_index] = image.pixels[img_index];
}
}
}