マルチページTIFFの編集について

解決


himizu  2012-05-18 13:13:37  No: 147600  IP: 192.*.*.*

マルチページTIFFファイルの各ページの画像を回転し、保存しようとしています。
マルチページTIFFの各フレームを回転させて保存したいのですが、うまくいきません。


    TIFFデータ:3ページのTIFF画像

*********************************************************************
    Dim img As Image = Image.FromFile(filepath)
    Dim fd As New FrameDimension(img.FrameDimensionsList(0))
    Dim frameCount As Integer = img.GetFrameCount(fd)

    For i = 0 To frameCount - 1
        'フレームを選択
        img.SelectActiveFrame(fd, i)
        
        '画像を回転
        img.RotateFlip(RotateFlipType.Rotate90FlipXY)
    Next i

    img.Save(filepath, System.Drawing.Imaging.ImageFormat.Tiff)
    img.Dispose()
*********************************************************************


上記だと、保存後のTIFF画像は、3ページの内の1ページ目の画像が3回転され、
2、3ページ目がなくなって保存されてしまいます。


元TIFFファイルの各ページを90度回転させて保存させたいのですが。。

編集 削除
魔界の仮面弁士  2012-05-20 18:13:41  No: 147601  IP: 192.*.*.*

> 上記だと、保存後のTIFF画像は、3ページの内の1ページ目の画像が3回転され、
RotateFlip すると、他のページが破棄されるためです。
回転前後で、GetFrameCount の戻り値を比較してみましょう。
(なお、SelectActiveFrame は存在しないページを指定してもエラーになりません)


> 2、3ページ目がなくなって保存されてしまいます。
後続ページを保存するためには、Save メソッドではなく SaveAdd メソッドを使います。

先頭ページを Save する際には、EncoderValue.MultiFrame を指定し、
後続ページの SaveAdd では、EncoderValue.FrameDimensionPage を指定します。



以下サンプル。Win7 で検証しています。

'Option Strict On
'Imports System.IO
'Imports System.Drawing.Imaging


'【回転後の結果を保存するファイル名】
Dim sFolder As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments
Dim newFile As String = Path.Combine(sFolder, "new.tif")


'【回転させる前の元画像ファイル名】
Dim oldFile As String = Path.Combine(sFolder, "old.tif")
'Dim url As String = "http://www.nifty.com/keibabook/image/kbnet_sample.tif"
'If File.Exists(oldFile) Then
'    File.Delete(oldFile)
'End If
'My.Computer.Network.DownloadFile(url, oldFile)


'【以下が本題の処理】
Dim tiffEncoder As ImageCodecInfo = ImageCodecInfo.GetImageEncoders().Where( _
    Function(codec) codec.MimeType = "image/tiff").First()

'[Creating and Saving a Multiple-Frame Image]
'http://msdn.microsoft.com/en-us/library/ms533839(VS.85).aspx
'色深度や圧縮方法などは、適宜調整してください。
Dim encParams As New EncoderParameters(3)
encParams.Param(0) = New EncoderParameter(Encoder.SaveFlag, CLng(EncoderValue.MultiFrame))
encParams.Param(1) = New EncoderParameter(Encoder.ColorDepth, 1L)
encParams.Param(2) = New EncoderParameter(Encoder.Compression, CLng(EncoderValue.CompressionCCITT3))

Dim page As New FrameDimension(FrameDimension.Page.Guid)
Using oldStream As New MemoryStream(File.ReadAllBytes(oldFile)), _
      newStream As New MemoryStream(), _
      baseImage As Image = Image.FromStream(oldStream)

    Dim frameCount As Integer = baseImage.GetFrameCount(page)
    baseImage.RotateFlip(RotateFlipType.Rotate90FlipXY)
    baseImage.Save(newStream, tiffEncoder, encParams)

    encParams.Param(0) = New EncoderParameter(Encoder.SaveFlag, CLng(EncoderValue.FrameDimensionPage))
    For p As Integer = 1 To frameCount - 1
        Using oldImage As New Bitmap(oldFile)
            oldImage.SelectActiveFrame(page, p)
            oldImage.RotateFlip(RotateFlipType.Rotate90FlipXY)
            baseImage.SaveAdd(oldImage, encParams)
        End Using
    Next

    'newStream の内容をファイルに保存する
    File.WriteAllBytes(newFile, newStream.ToArray())
End Using

編集 削除
himizu  2012-06-07 19:45:42  No: 147602  IP: 192.*.*.*

>魔界の仮面弁士さま

いつも有難う御座います。
ご返信頂いた内容にて、想定する動作をしました。

編集 削除