1

.NETでシンプルな画像ビューアを構築し、ブラウザにマルチフレームTIFF画像を表示する必要があります。現在、マルチフレームTIFFと同じデータベースに混在しているJPEGをストリーミングバックする(ashx)ハンドラー設定があり、このハンドラーはTIFFファイルの最初のフレームも現在の状態で返すことに注意してください。 。以下のVB.NETコード(ハンドラーの一部)では、TIFFファイルに複数のフレームがあるかどうかを識別でき、フレームをつなぎ合わせようとしましたが、まだ成功していません。同様のアプローチを使用してマルチフレームTIFFを返品した人はいますか?注:以下のコードを開発する際の参考として、マルチフレームTIFF画像を開く方法を使用しました。

        context.Response.Cache.SetCacheability(HttpCacheability.NoCache)
        context.Response.Cache.SetNoStore()
        context.Response.Cache.SetExpires(DateTime.MinValue)

        imageList = GetPhoto(picid)
        If (imageList IsNot Nothing) Then
            Dim img As Image
            Dim prevImageHeight = 0
            For Each img In imageList
                Dim imgGraphics As Graphics = Graphics.FromImage(img)
                imgGraphics.DrawImage(img, 0, prevImageHeight, img.Width, img.Height * imageList.Count)
                prevImageHeight += img.Height
                img.Save(context.Response.OutputStream, ImageFormat.Jpeg)
                img.Dispose()
            Next img
        Else
            ' Return 404
            context.Response.StatusCode = 404
            context.Response.End()
        End If

GetPhoto関数のコードは次のとおりです。

Public Function GetPhoto(ByVal id As String) As List(Of Image)
    Dim db As New UtilDb
    Dim imageLocation As String
    Dim errMsg As String = ""
    Dim imageList As New List(Of Image)
    Dim returnImage As Bitmap = Nothing
    imageLocation = GetFileName(id)

    If (imageLocation IsNot Nothing) Then
        Dim iFile As Image = Image.FromFile(imageLocation)
        If (imageLocation.ToUpper.EndsWith("TIF")) Then
            Dim frameCount As Integer = iFile.GetFrameCount(FrameDimension.Page)
            Dim i As Integer
            If (frameCount > 1) Then
                For i = 0 To frameCount - 1
                    iFile.SelectActiveFrame(FrameDimension.Page, i)
                    returnImage = New Bitmap(iFile, iFile.Width * 0.4, iFile.Height * 0.4)
                    imageList.Add(returnImage)
                Next i
            Else
                returnImage = New Bitmap(iFile, iFile.Width * 0.4, iFile.Height * 0.4)
                imageList.Add(returnImage)
            End If

        Else
            Dim scaledWidth As Integer = (iFile.Width / iFile.Height) * 480
            returnImage = New Bitmap(iFile, scaledWidth, 480)
            imageList.Add(returnImage)
        End If
        iFile.Dispose()
    End If
    Return imageList
End Function

マルチフレームTIFFの各フレームを連続した画像に配置してブラウザに送り返すことは可能ですか?マルチフレームTIFFをPDFなどの別の形式に変換することに力を注ぐ必要がありますか?私は基本的に変換パッケージを購入するための予算を持っていません...どんな助けやガイダンスも大歓迎です!

4

2 に答える 2

3

したがって、ソリューションは非常にシンプルになりました.ブラウザでレンダリングされるフレームがトップフレームだけであった主な理由は、各フレームを個別に応答ストリームに保存することであることに気付きました.

これは、画像から必要なすべてのパラメーターを収集するために作成した関数のスニペットです (ただし、マルチフレーム TIFF、シングルフレーム TIFF、または JPEG)。

Dim iFile As Image = Image.FromFile(imageLocation)
Dim frameCount As Integer = iFile.GetFrameCount(FrameDimension.Page)
Dim totalWidth, totalHeight As Integer

If (imageLocation.ToUpper.EndsWith("TIF")) Then
    Dim i As Integer
    If (frameCount > 1) Then
        totalWidth = 0
        totalHeight = 0
        For i = 0 To frameCount - 1
            iFile.SelectActiveFrame(FrameDimension.Page, i)
            imageStructure.totalWidth = Math.Max(totalWidth, (iFile.Width * 0.4))
            imageStructure.totalHeight += (iFile.Height * 0.4)
            returnImage = New Bitmap(iFile, iFile.Width * 0.4, iFile.Height * 0.4)
            imageList.Add(returnImage)
        Next i
     Else
        returnImage = New Bitmap(iFile, iFile.Width * 0.4, iFile.Height * 0.4)
        imageStructure.totalWidth = (iFile.Width * 0.4)
        imageStructure.totalHeight = (iFile.Height * 0.4)
        imageList.Add(returnImage)
     End If

 Else
    Dim scaledWidth As Integer = (iFile.Width / iFile.Height) * defaultHeight
    returnImage = New Bitmap(iFile, scaledWidth, defaultHeight)
    imageStructure.totalWidth = scaledWidth
    imageStructure.totalHeight = defaultHeight
    imageList.Add(returnImage)
 End If
 iFile.Dispose()
 imageStructure.frameCount = frameCount
 imageStructure.frameList = imageList

画像をレンダリングするコードのスニペットを次に示します。

If (imageStructure.frameCount > 1) Then
   'We know we have a multi-frame TIFF
   Dim appendedImage As Bitmap = New Bitmap(imageStructure.totalWidth, imageStructure.totalHeight)
   imgGraphics = Graphics.FromImage(appendedImage)
   Dim prevHeight As Integer = 0
   For Each img In imageStructure.frameList
         imgGraphics.DrawImage(img, 0, prevHeight, img.Width, img.Height)
         prevHeight += img.Height
         img.Dispose()
   Next
   appendedImage.Save(context.Response.OutputStream, ImageFormat.Jpeg)
   appendedImage.Dispose()
Else
    ' JPEG or single frame TIFF
    img = imageStructure.frameList(0)
    imgGraphics = Graphics.FromImage(img)
    imgGraphics.DrawImage(img, 0, 0, img.Width, img.Height)
    img.Save(context.Response.OutputStream, ImageFormat.Jpeg)
    img.Dispose()
 End If

注: imageStructure 変数は、合計の幅、高さ、フレーム数、および各フレームを表す画像のリストを格納する簡単な構造です。

これで、リファクタリングを行うだけで準備完了です。他の誰かがこれが役立つことを願っています...

于 2009-08-11T16:37:03.073 に答える
3

ありがとうございます!とても参考になりました。これを C# に変換し、tiff ファイルのページ数に関係なく常にループするようにして、少し短くしました。また、構造体を削除し、代わりに変数を使用しました。以下はコードです:

protected void Page_Load(object sender, EventArgs e)
{
    string cFileName = Request.QueryString["cFileName"];

    if (cFileName != null && cFileName.ToString().Trim().Length > 0)
    {

        Image iFile = Image.FromFile(cFileName.ToString().Trim());
        MemoryStream imgStream = new MemoryStream();

        int i = 0;
        int frameCount = iFile.GetFrameCount(FrameDimension.Page);

        List<Image> imageList = new List<Image>();
        Image returnImage;
        Graphics imgGraphics;

        int totalWidth = 0;
        int nStatus = 0;
        int totalHeight = 0;

        if (cFileName.ToUpper().Trim().EndsWith("TIF") || cFileName.ToUpper().Trim().EndsWith("TIFF"))
        {
            if (frameCount > 0)
            {
                for (i = 0; i < frameCount; i++)
                {
                    nStatus = iFile.SelectActiveFrame(FrameDimension.Page, i);
                    totalWidth = (int)Math.Max(totalWidth, (iFile.Width) * 0.4);
                    totalHeight += (int)(iFile.Height * 0.4);

                    returnImage = new Bitmap(iFile, (int)(iFile.Width * 0.4), (int)(iFile.Height * 0.4));
                    imageList.Add(returnImage);
                }
            }
        }
        else
        {
            returnImage = new Bitmap(iFile, (int)(iFile.Width), (int)(iFile.Height));
            totalWidth = (int)(iFile.Width);
            totalHeight = (int)(iFile.Height);

            imageList.Add(returnImage);
        }

        iFile.Dispose();

        if (frameCount > 0)
        {
            Bitmap appendedImage = new Bitmap(totalWidth, totalHeight);
            imgGraphics = Graphics.FromImage(appendedImage);
            int prevHeight = 0;

            foreach (Image iImage in imageList)
            {
                imgGraphics.DrawImage(iImage, 0, prevHeight, iImage.Width, iImage.Height);
                prevHeight += iImage.Height;
                iImage.Dispose();
            }
            appendedImage.Save(Context.Response.OutputStream, ImageFormat.Jpeg);
            appendedImage.Dispose();
        }

    }
}
于 2011-02-25T20:18:45.827 に答える