我正在尝试拆分和合并多页 tiff 图像。我拆分的原因是在每个图像级别绘制注释。代码运行良好,但是与源 tiff 相比,合并的 tiff 相当大。例如,我用 17 个彩色页面的 tiff 图像(大小为 5MB)进行了测试,经过拆分和合并,它产生了 85MB 的 tiff 图像。我正在使用 BitMiracle.LibTiff。我实际上也临时注释了注释代码来解决这个大小问题,我不确定我做错了什么。这是要拆分的代码。
private List<Bitmap> SplitTiff(byte[] imageData)
{
var bitmapList = new List<Bitmap>();
var tiffStream = new TiffStreamForBytes(imageData);
//open tif file
var tif = Tiff.ClientOpen("", "r", null, tiffStream);
//get number of pages
var num = tif.NumberOfDirectories();
if (num == 1)
return new List<Bitmap>
{
new Bitmap(GetImage(imageData))
};
for (short i = 0; i < num; i++)
{
//set current page
tif.SetDirectory(i);
FieldValue[] photoMetric = tif.GetField(TiffTag.PHOTOMETRIC);
Photometric photo = Photometric.MINISBLACK;
if (photoMetric != null && photoMetric.Length > 0)
photo = (Photometric)photoMetric[0].ToInt();
if (photo != Photometric.MINISBLACK && photo != Photometric.MINISWHITE)
bitmapList.Add(GetBitmapFromTiff(tif));
// else
// bitmapList.Add(GetBitmapFromTiffBlack(tif, photo));// commented temporrarly to fix size issue
}
return bitmapList;
}
private static Bitmap GetBitmapFromTiff(Tiff tif)
{
var value = tif.GetField(TiffTag.IMAGEWIDTH);
var width = value[0].ToInt();
value = tif.GetField(TiffTag.IMAGELENGTH);
var height = value[0].ToInt();
//Read the image into the memory buffer
var raster = new int[height * width];
if (!tif.ReadRGBAImage(width, height, raster))
{
return null;
}
var bmp = new Bitmap(width, height, PixelFormat.Format32bppRgb);
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
var bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
var bits = new byte[bmpdata.Stride * bmpdata.Height];
for (var y = 0; y < bmp.Height; y++)
{
int rasterOffset = y * bmp.Width;
int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride;
for (int x = 0; x < bmp.Width; x++)
{
int rgba = raster[rasterOffset++];
bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff);
bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff);
bits[bitsOffset++] = (byte)(rgba & 0xff);
bits[bitsOffset++] = (byte)((rgba >> 24) & 0xff);
}
}
System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length);
bmp.UnlockBits(bmpdata);
return bmp;
}
并且将单个位图合并到 tiff 的代码在这里...
public static PrizmImage PrizmImageFromBitmaps(List<Bitmap> imageItems, string ext)
{
if (imageItems.Count == 1 && !(ext.ToLower().Equals(".tif") || ext.ToLower().Equals(".tiff")))
return new PrizmImage(new MemoryStream(ImageUtility.BitmapToByteArray(imageItems[0])), ext);
var codecInfo = GetCodecInfo();
var memoryStream = new MemoryStream();
var encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
var initialImage = imageItems[0];
var masterBitmap = imageItems[0];// new Bitmap(initialImage);
masterBitmap.Save(memoryStream, codecInfo, encoderParams);
encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
for (var i = 1; i < imageItems.Count; i++)
{
var img = imageItems[i];
masterBitmap.SaveAdd(img, encoderParams);
img.Dispose();
}
encoderParams.Param[0] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.Flush);
masterBitmap.SaveAdd(encoderParams);
memoryStream.Seek(0, SeekOrigin.Begin);
encoderParams.Dispose();
masterBitmap.Dispose();
return new PrizmImage(memoryStream, ext);
}