Flux (et convertir?) TIFF de plusieurs pages en utilisant ASP.NET
-
12-09-2019 - |
Question
J'ai construit simple visionneuse d'images dans .NET et ont l'obligation d'afficher les images TIFF multi-images dans le navigateur. À l'heure actuelle, j'ai un (ashx) la configuration du gestionnaire de flux fichiers JPEG qui sont co-mêlés dans la même base que la valeur de mentionner de TIFF multi-cadre et il est que ce gestionnaire retourne également la première image du fichier TIFF dans son état actuel . Dans le code ci-dessous VB.NET (partie du gestionnaire) Je suis en mesure d'identifier si un fichier TIFF contenant plusieurs images et j'ai commencé à tenter de raccorder les images, mais ont pas encore eu aucun succès. Quelqu'un at-il retourné TIFF multi-cadre de l'aide d'une approche similaire? Remarque: J'ai utilisé le Comment ouvrir une image TIFF multi-images comme référence lors de l'élaboration du code ci-dessous.
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
Voici le code de la fonction 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
Est-il possible de placer chaque image d'une image TIFF multi-images dans une image contiguë et l'envoyer au navigateur? Dois-je concentrer mon énergie sur la conversion de la mutli-cadre TIFF à un autre format tel que PDF? Je n'ai pas essentiellement un budget pour l'achat de paquets de conversion ... Toute aide ou des conseils seraient grandement appréciés!
La solution
Donc, la solution a fini par être très simple -. Je réalise que l'enregistrement de chaque image individuellement au courant de réponse a été la principale raison pour laquelle le cadre supérieur était le seul cadre étant rendu dans le navigateur
Voici un extrait de la fonction que j'ai écrit pour recueillir tous les paramètres nécessaires à partir d'une image (bien que TIFF multi-images de, TIFF simple cadre de, ou des fichiers 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
Voici un extrait du code qui rend les images:
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
Note: La variable imageStructure est une structure trivial qui stocke la largeur totale, la hauteur, le nombre de trames, et une liste d'images représentant chaque trame
.Maintenant, je viens de refactoring faire et je serai tous ensemble! J'espère que quelqu'un d'autre trouve cela utile ...
Autres conseils
Merci beaucoup !, c'était vraiment utile. Je traduis à C # et en a fait un peu plus court en boucle toujours quel que soit le nombre de pages dans le fichier TIFF. J'ai aussi éliminé la structure et les variables d'utilisation à la place. Voici le code:
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();
}
}
}