使用ASP.NET流(并转换?)多页TIFF

时间:2009-08-10 13:52:41

标签: asp.net vb.net tiff ihttphandler

我在.NET中构建了一个简单的图像查看器,并且要求在浏览器中显示多帧TIFF图像。目前,我有一个(ashx)处理程序设置来流回与在多帧TIFF相同的数据库中混合的JPEG,并且值得一提的是,此处理程序还将返回当前状态下TIFF文件的第一帧。在下面的VB.NET代码(处理程序的一部分)中,我能够识别TIFF文件是否有多个帧,并且我开始尝试将帧拼接在一起但尚未取得任何成功。有没有人使用类似的方法返回多帧TIFF? 注意:我在开发以下代码时使用How to open a multi-frame TIFF image作为参考。

        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吗?我基本上没有购买转换套餐的预算......非常感谢任何帮助或指导!

2 个答案:

答案 0 :(得分: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变量是一个简单的结构,它存储了总宽度,高度,帧数以及代表每个帧的图像列表。

现在我只需进行一些重构,我将全力以赴!我希望其他人觉得这很有用......

答案 1 :(得分:3)

非常感谢!,这真的很有帮助。无论tiff文件中的页数是多少,我都将它翻译成C#,并通过循环来缩短它。我也取消了结构并使用变量。以下是代码:

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();
        }

    }
}