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