1

我在 .NET 中构建了一个简单的图像查看器,并且需要在浏览器中显示多帧 TIFF 图像。目前,我有一个(ashx)处理程序设置来流回与多帧 TIFF 混合在同一个数据库中的 JPEG,值得一提的是,该处理程序还将返回 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 回答