使用 ASP.NET 流式传输(并转换?)多页 TIFF
-
12-09-2019 - |
题
我在.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)?我基本上没有购买转换包的预算...任何帮助或指导将不胜感激!
解决方案
因此,溶液最终成为非常简单的 - 我意识到,单独地保存各帧响应流是主要的原因,顶部框架是唯一的帧在浏览器中被呈现
下面是从我写收集所有必需的参数的从图像的功能的代码段(虽然多帧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变量是存储的总宽度,高度,帧的数量,并且表示每个帧图像的列表的琐碎结构
。现在我只是有一些重构要做,我将所有设置!我希望别人发现这个有用...
其他提示
感谢你这么多!这是真的很有帮助。我把它翻译成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();
}
}
}
不隶属于 StackOverflow