如何优化此代码以创建 TIFF 文件和/或应考虑哪些备用库以提高性能

本文关键字:高性能 备用 文件 优化 何优化 TIFF 创建 代码 | 更新日期: 2024-10-29 23:15:21

我正在创建一个进程来提取TIFF,对其中一个图像执行操作,然后重建TIFF。中间的操作并不重要,但是,提取和重建在处理方面被证明是非常昂贵的。

const string tifPath = "14 page.TIFF";
MemoryStream[] imageStreams;
var stream = new MemoryStream();
//extract tiff
using (var imageFile = Image.FromFile(tifPath))
{
    var imagePageCount = imageFile.GetFrameCount(FrameDimension.Page);
    imageStreams = new MemoryStream[imagePageCount];
    var frameDimension = new FrameDimension(imageFile.FrameDimensionsList[0]);
    for (var i = 0; i < imagePageCount; i++)
    {
        imageFile.SelectActiveFrame(frameDimension, i);
        var bmp = new Bitmap(imageFile);
        bmp.Save(stream, ImageFormat.Bmp);
        imageStreams[i] = stream;
    }
}
//build tiff
var encoder = Encoder.SaveFlag;
var encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
stream = new MemoryStream();
var firstImage = new Bitmap(Image.FromStream(imageStreams[0]));
firstImage.Save(stream, encoderInfo, encoderParameters);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
for (var i = 1; i < imageStreams.Length; i++)
{
    var img = Image.FromStream(imageStreams[i]);
    firstImage.SaveAdd(img, encoderParameters);
}
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
firstImage.SaveAdd(encoderParameters);

我发现清理我的溪流在某些地方有所帮助。使用Microsoft和其他库(LeadTools 和 LibTiff),平均大约需要 5 秒。我不打算使用 C# 解决方案,而是试图找到一种方法来尽可能减少它。

如何优化此代码以创建 TIFF 文件和/或应考虑哪些备用库以提高性能

我找不到并行化创建过程的好方法。尝试从在 Parallel.ForEach 外部构建的 MemoryStream 构建映像只会引发一般的 GDI+ 错误。

const string tifPath = "14 Page.TIFF";
//extract tiff
var imageFile = Image.FromFile(tifPath);
var imagePageCount = imageFile.GetFrameCount(FrameDimension.Page);
var imageStreams = new Bitmap[imagePageCount];
var rangePartioner = Partitioner.Create(0, imagePageCount);
var frameDimension = new FrameDimension(imageFile.FrameDimensionsList[0]);
imageFile.Dispose();
Parallel.ForEach(rangePartioner, (range, loopState) =>
{
    for (var i = range.Item1; i < range.Item2; i++)
    {
        using (var imageFile2 = Image.FromFile(tifPath))
        {
            imageFile2.SelectActiveFrame(frameDimension, i);
            imageStreams[i] = new Bitmap(imageFile2);
        }
    }
});
//build tiff
var encoder = Encoder.SaveFlag;
var encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
var encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(encoder, (long) EncoderValue.MultiFrame);
var stream2 = new MemoryStream();
using(var firstImage = imageStreams[0])
{
    firstImage.Save(stream2, encoderInfo, encoderParameters);
    encoderParameters.Param[0] = new EncoderParameter(encoder, (long) EncoderValue.FrameDimensionPage);
    for (var i = 1; i < imageStreams.Length; i++)
    {
        firstImage.SaveAdd(imageStreams[i], encoderParameters);
    }
    encoderParameters.Param[0] = new EncoderParameter(encoder, (long) EncoderValue.Flush);
    firstImage.SaveAdd(encoderParameters);
}           

这缩短了大约 2 秒。仍然在寻找处理下半场的好方法。

编辑:添加了仅转换图像而不将其保存到流的建议更改。编辑:添加了其余的修复。

开始分析你的代码,看看哪些部分需要时间。很难假设事情。您可以并行提取 TIFF,与构建相同。这将使您获得 4 倍的加速。