tiff ファイルの最後のページで何らかの作業を行う必要があるという課題に直面しています。だから私は以下のサンプルコードを書きましたが、動作しますが、動作が遅いだけです。コードは最終的にかなり実行されるので、高速化する必要があります。
マルチスレッドで実行するというアイデアを試してみましたが、最終的にはすべてのデータを同じファイルに書き込む必要があり、時間がかかるように見えるため、うまくいくとは思いません。
最後のページだけで作業する方法、またはまだ考えていないことを教えてくれる答えを期待しています。
private void rotateLastPage() {
string inputfile = "C:\\input.tif";
string tmpfile = inputfile + ".tmp";
Bitmap bmap = (Bitmap)Image.FromFile(inputfile);
int max = bmap.GetFrameCount(FrameDimension.Page);
Image[] images = new Image[max];
int i;
for (i = 0; i < max; i++)
{
bmap.SelectActiveFrame(FrameDimension.Page, i);
images[i] = (Image)bmap.Clone();
}
bmap.Dispose();
Bitmap pages = null;
i = 0;
foreach(Image image in images)
{
try
{
if (i == max - 1)
{
image.RotateFlip(RotateFlipType.Rotate90FlipNone);
}
EncoderParameters encoderParameters = new EncoderParameters(2);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame);
Int16 c = BitConverter.ToInt16(image.PropertyItems[Array.IndexOf(image.PropertyIdList, 0x103)].Value, 0);
if (c != 4 && c != 5)
{
throw new ArgumentException("Only CCIT4 and LZW compressed images are allowed.");
}
else if (c == 4)
{
encoderParameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
}
else if (c == 5)
{
encoderParameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)EncoderValue.CompressionLZW);
}
if (i == 0)
{
pages = (Bitmap)image;
ImageCodecInfo encoder = getTiffEncoder();
pages.Save(tmpfile, encoder, encoderParameters);
}
else
{
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage);
pages.SaveAdd(image, encoderParameters);
}
if (i == max - 1)
{
encoderParameters = new EncoderParameters(1);
encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush);
pages.SaveAdd(encoderParameters);
}
i++;
}
catch (Exception e)
{
Console.WriteLine(String.Format("Unable to rotate page {0} in file {1} due to {2}", (i + 1).ToString(), inputfile, e.Message));
break;
}
}
foreach (Image image in images) {
image.Dispose();
}
pages.Dispose();
// eventually overwrite input file with tmp file
}
private static ImageCodecInfo getTiffEncoder()
{
ImageCodecInfo encoder = null;
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i < encoders.Length; i++)
{
if (encoders[i].MimeType == "image/tiff")
{
encoder = encoders[i];
}
}
if (encoder == null)
{
throw new NotSupportedException("Unable to find a tiff encoder.");
}
return encoder;
}