C #: Como faço para converter um TIFF de várias páginas via MemoryStream em uma imagem longa?

Então, eu pude pegar um arquivo TIFF de várias páginas e convertê-lo em uma única imagem jpeg, mas ele achata o TIFF. Por achatar, quero dizer que só retorna a primeira página. O objective é recuperar o TIFF (via stream de memory), abrir cada página do TIFF e anexá-lo a um novo jpeg (ou qualquer imagem da web). Criando assim uma imagem longa para visualizar na web sem o auxílio de um plugin. Eu tenho o MODI.dll instalado, mas não tenho certeza como usá-lo nesta instância, mas é uma opção.

  • Código fonte (usando um FileHandler):

    #region multi-page tiff to single page jpeg var byteFiles = dfSelectedDocument.File.FileBytes; // <-- FileBytes is a byte[] or byte array source. byte[] jpegBytes; using( var inStream = new MemoryStream( byteFiles ) ) using( var outStream = new MemoryStream() ) { System.Drawing.Image.FromStream( inStream ).Save( outStream, ImageFormat.Jpeg ); jpegBytes = outStream.ToArray(); } context.Response.ContentType = "image/JPEG"; context.Response.AddHeader( "content-disposition", string.Format( "attachment;filename=\"{0}\"", dfSelectedDocument.File.FileName.Replace( ".tiff", ".jpg" ) ) ); context.Response.Buffer = true; context.Response.BinaryWrite( jpegBytes ); #endregion 

Eu estou supondo que você terá que percorrer cada quadro no TIFF.

Aqui está um trecho do arquivo tiff multi-página Split :

 private void Split(string pstrInputFilePath, string pstrOutputPath) { //Get the frame dimension list from the image of the file and Image tiffImage = Image.FromFile(pstrInputFilePath); //get the globally unique identifier (GUID) Guid objGuid = tiffImage.FrameDimensionsList[0]; //create the frame dimension FrameDimension dimension = new FrameDimension(objGuid); //Gets the total number of frames in the .tiff file int noOfPages = tiffImage.GetFrameCount(dimension); ImageCodecInfo encodeInfo = null; ImageCodecInfo[] imageEncoders = ImageCodecInfo.GetImageEncoders(); for (int j = 0; j < imageEncoders.Length; j++) { if (imageEncoders[j].MimeType == "image/tiff") { encodeInfo = imageEncoders[j]; break; } } // Save the tiff file in the output directory. if (!Directory.Exists(pstrOutputPath)) Directory.CreateDirectory(pstrOutputPath); foreach (Guid guid in tiffImage.FrameDimensionsList) { for (int index = 0; index < noOfPages; index++) { FrameDimension currentFrame = new FrameDimension(guid); tiffImage.SelectActiveFrame(currentFrame, index); tiffImage.Save(string.Concat(pstrOutputPath, @"\", index, ".TIF"), encodeInfo, null); } } } 

Você deve ser capaz de adaptar a lógica acima para acrescentar ao seu JPG, em vez de criar arquivos separados.

Caso você receba o terrível erro “Ocorreu um erro genérico no GDI +” (que é indiscutivelmente o Rickroll de todos os erros) ao usar o método SelectActiveFrame sugerido nas outras respostas, sugiro usar o System.Windows.Media.Imaging.TiffBitmapDecoder class em vez disso (você precisará adicionar uma referência à biblioteca de estrutura PresentationCore.dll ).

Aqui está um código de exemplo que faz exatamente isso (coloca todos os frameworks TIFF em uma lista de Bitmaps padrão):

 List bmpLst = new List(); using (var msTemp = new MemoryStream(data)) { TiffBitmapDecoder decoder = new TiffBitmapDecoder(msTemp, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); int totFrames = decoder.Frames.Count; for (int i = 0; i < totFrames; ++i) { // Create bitmap to hold the single frame System.Drawing.Bitmap bmpSingleFrame = BitmapFromSource(decoder.Frames[i]); // add the frame (as a bitmap) to the bitmap list bmpLst.Add(bmpSingleFrame); } } 

E aqui está o método auxiliar BitmapFromSource :

 public static Bitmap BitmapFromSource(BitmapSource bitmapsource) { Bitmap bitmap; using (var outStream = new MemoryStream()) { BitmapEncoder enc = new BmpBitmapEncoder(); enc.Frames.Add(BitmapFrame.Create(bitmapsource)); enc.Save(outStream); bitmap = new Bitmap(outStream); } return bitmap; } 

Para mais informações sobre esta solução, sugiro também ler este post que escrevi.