2009-08-10 2 views
1

저는 .NET에서 간단한 이미지 뷰어를 구축했으며 브라우저에 멀티 프레임 TIFF 이미지를 표시해야합니다. 현재, 멀티 프레임 TIFF와 동일한 데이터베이스에 공동으로 혼합 된 JPEG을 스트리밍하기위한 (ashx) 핸들러 설정이 있으며,이 핸들러가 현재 상태의 TIFF 파일의 첫 번째 프레임을 반환한다는 점을 언급 할 가치가 있습니다 . 아래의 VB.NET 코드 (핸들러의 일부)에서 TIFF 파일에 여러 프레임이 있고 프레임을 함께 스티칭하려고 시도했지만 아직 어떤 성공도 얻지 못했는지 확인할 수 있습니다. 멀티 프레임 TIFF가 비슷한 방식으로 반환 된 사람이 있습니까? 참고 : 아래 코드를 개발할 때 How to open a multi-frame TIFF image을 참조로 사용했습니다.ASP.NET을 사용하여 다중 페이지 TIFF를 스트리밍 (및 변환)

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의 각 프레임을 배치하고 브라우저로 다시 보낼 수 있나요 : 여기

 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 기능에 대한 코드? 다중 프레임 TIFF를 PDF와 같은 다른 형식으로 변환하는데 전력을 집중해야합니까? 본질적으로 전환 패키지 구매에 대한 예산이 없습니다 ... 어떤 도움이나 지침도 크게 감사하겠습니다!

답변

3

솔루션이 정말 간단 해졌습니다. 각 프레임을 개별적으로 응답 스트림에 저장하는 것이 상위 프레임이 브라우저에서 렌더링되는 유일한 프레임이었던 주된 이유였습니다. 여기

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 

가에서 미리보기입니다 : 여기

는 (멀티 프레임 TIFF의이기는하지만, 단일 프레임 TIFF의 또는 JPEG 파일) 나는 이미지에서 필요한 모든 매개 변수를 수집하기 위해 쓴 함수의 코드 조각입니다 이미지를 렌더링하는 코드 :

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 변수는 전체 폭, 높이, 프레임 번호, 각 프레임을 나타내는 이미지의 목록을 저장하는 단순 구조이다.

이제 리팩터링을 수행하기 만하면됩니다. 나는 다른 사람이 유용하다고 생각하기를 바랍니다.

3

정말 고마워요. 이것은 정말로 도움이되었습니다. 나는 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(); 
     } 

    } 
} 
관련 문제