2009-08-10 12 views
1

Ich habe einen einfachen Bildbetrachter in .NET gebaut und haben die Anforderung, Multi-Frame-TIFF-Bilder im Browser anzuzeigen. Zur Zeit habe ich ein (ashx) Handler-Setup, um JPEGs zu streamen, die sich in derselben Datenbank wie die Multi-Frame-TIFFs befinden, und es ist erwähnenswert, dass dieser Handler auch den ersten Frame der TIFF-Datei in ihrem aktuellen Zustand zurückgibt . In dem VB.NET-Code unten (Teil des Handlers) kann ich feststellen, ob eine TIFF-Datei mehrere Frames hat und ich habe versucht, die Frames zusammenzufügen, hatte aber noch keinen Erfolg. Hat jemand Multi-Frame-TIFFs mit einem ähnlichen Ansatz zurückgegeben? Hinweis: Ich habe die How to open a multi-frame TIFF image als Referenz bei der Entwicklung des folgenden Codes verwendet. HierStream (und konvertieren?) Mehrseitige TIFF mit ASP.NET

 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 

ist der Code für die GetPhoto Funktion:

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 

Ist es möglich, jeden Rahmen eines Multi-Frame-TIFF in einem zusammenhängenden Bild zu platzieren und es zurück an den Browser schicken? Sollte ich meine Energie darauf konzentrieren, das Mehrfachrahmen-TIFF in ein anderes Format wie PDF zu konvertieren? Ich habe im Grunde kein Budget für den Kauf von Conversion-Paketen ... Jede Hilfe oder Beratung wäre sehr willkommen!

Antwort

3

So war die Lösung wirklich einfach - ich erkannte, dass das Speichern jedes Frames einzeln im Antwort-Stream der Hauptgrund dafür war, dass der oberste Frame der einzige Frame war, der im Browser gerendert wurde.

Hier ist ein Ausschnitt aus der Funktion, die ich schrieb alle erforderlichen Parameter von einem Bild (wenn auch Multi-Frame-TIFF, Single-Frame-TIFF oder JPEG-Dateien) zu sammeln:

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 

Hier ist ein Ausschnitt aus dem Code, der die Bilder macht:

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 

Anmerkung: die imageStructure Variable ist eine triviale Struktur, die die gesamte Breite, Höhe, Anzahl der Rahmen, und eine Liste der Bilder, die jeden Rahmen speichert.

Jetzt habe ich nur etwas Refactoring zu tun und ich werde alles eingestellt sein! Ich hoffe, jemand anderes findet dieses nützliche ...

3

Vielen Dank !, das war wirklich hilfreich. Ich übersetzte es in C# und machte es etwas kürzer, indem ich immer in der Schleife lief, unabhängig von der Anzahl der Seiten in der TIFF-Datei. Ich habe auch die Struktur eliminiert und stattdessen Variablen verwendet. Unten ist der 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(); 
     } 

    } 
} 
Verwandte Themen