2008-12-29 20 views

Respuesta

74

de inicio con el primer mapa de bits poniéndolo en un objeto de imagen

Bitmap bitmap = (Bitmap)Image.FromFile(file); 

Guardar el mapa de bits de memoria como tiff

MemoryStream byteStream = new MemoryStream(); 
bitmap.Save(byteStream, ImageFormat.Tiff); 

Put Tiff en otro objeto Imagen

Image tiff = Image.FromStream(byteStream) 

Prepare codificadores:

ImageCodecInfo encoderInfo = GetEncoderInfo("image/tiff"); 

EncoderParameters encoderParams = new EncoderParameters(2); 
EncoderParameter parameter = new EncoderParameter(
    Encoder.Compression, (long)EncoderValue.CompressionCCITT4); 
encoderParams.Param[0] = parameter; 
parameter = new EncoderParameter(Encoder.SaveFlag, 
    (long)EncoderValue.MultiFrame); 
encoderParams.Param[1] = parameter; 

Guardar como archivo:

tiff.Save(sOutFilePath, encoderInfo, encoderParams); 

Para las páginas siguientes, se preparan los codificadores:

EncoderParameters EncoderParams = new EncoderParameters(2); 
EncoderParameter SaveEncodeParam = new EncoderParameter(
    Encoder.SaveFlag, 
    (long)EncoderValue.FrameDimensionPage); 
EncoderParameter CompressionEncodeParam = new EncoderParameter(
    Encoder.Compression, (long)EncoderValue.CompressionCCITT4); 
EncoderParams.Param[0] = CompressionEncodeParam; 
EncoderParams.Param[1] = SaveEncodeParam; 
tiff.SaveAdd(/* next image as tiff - do the same as above with memory */, EncoderParams); 

Por último enjuague el archivo:

EncoderParameter SaveEncodeParam = new EncoderParameter(
    Encoder.SaveFlag, (long)EncoderValue.Flush); 
EncoderParams = new EncoderParameters(1); 
EncoderParams.Param[0] = SaveEncodeParam; 
tiff.SaveAdd(EncoderParams); 

Eso debería empezar.

+4

Excelente respuesta. Solo podría ser más completo si describe cómo llegó a él (donde lo aprendió si no es por prueba y error), ya que los documentos de MSDN lo hacen casi imposible de entender. –

+0

Lo que me preguntaba es el uso de ImageFormat.Tiff en el método Save de MemoryStream - obviamente "la codificación" hecha más tarde es un proceso totalmente no relacionado - es decir, el vertido de bytes de la secuencia de memoria que se guardó utilizando ImageFormat.Tiff en un archivo no creará un archivo TIFF, supongo. –

+4

¿Qué es esa función "GetEncoderInfo"? –

3

Como no soy fanático de la trayectoria de Microsoft en lo que se refiere a manejar y crear archivos de formatos estandarizados, sugeriría utilizar ImageMagick, disponible como biblioteca .Net en el formulario MagickNet (cuidado, http://midimick.com/magicknet/ tiene actualmente una ventana emergente de spyware , He alertado al propietario del sitio).

19

Encontré esta publicación después de buscar un poco en Google. Probé el código que estaba en la publicación por a'b'c'd'e'f'g'h ', pero eso no funcionó para mí. Quizás, no estaba haciendo algo correctamente.

En cualquier caso, encontré otra publicación que guardaba imágenes en tiffs de varias páginas. Aquí está el enlace a la publicación: http://www.bobpowell.net/addframes.htm

Además, aquí está el código que funcionó para mí. Debería ser idéntico a esa publicación.

Encoder encoder = Encoder.SaveFlag; 
ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff"; 
EncoderParameters encoderParameters = new EncoderParameters(1); 
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame); 

// Save the first frame of the multi page tiff 
Bitmap firstImage = (Bitmap) _scannedPages[0].RawContent; 
firstImage.Save(fileName, encoderInfo, encoderParameters); 

encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage); 

// Add the remining images to the tiff 
for (int i = 1; i < _scannedPages.Count; i++) 
{ 
    Bitmap img = (Bitmap) _scannedPages[i].RawContent; 
    firstImage.SaveAdd(img, encoderParameters); 
} 

// Close out the file 
encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush); 
firstImage.SaveAdd(encoderParameters); 
+1

para gente perezosa como yo, ¡este código funcionaba fácilmente! – Pisu

2

Aquí está la operación dividida del archivo multi-tiff. Funciona igual que la función de cadena subserie. El primer índice de imagen será su MasterBitMap y seguirá agregando fotograma al MasterBitmap hasta el final del índice.

public void SaveMultiFrameTiff(int start, int end) 
    {    
     string outputFileName = "out.TIF"; 
     string inputFileName = "input.TIF";    

     try 
     {     

      Bitmap MasterBitmap = new Bitmap(inputFileName); //Start page of document(master) 
      Image imageAdd = Image.FromFile(inputFileName); //Frame Image that will be added to the master   
      Guid guid = imageAdd.FrameDimensionsList[0]; //GUID 
      FrameDimension dimension = new FrameDimension(guid); 
      // start index cannot be less than 0 and cannot be greater than frame count   
      if (start < 1 || end > MasterBitmap.GetFrameCount(dimension)) { return; }   

      EncoderParameters ep = new EncoderParameters(1); 

      //Get Image Codec Information 
      ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
      ImageCodecInfo codecInfo = codecs[3]; //image/tiff 

      //MultiFrame Encoding format 
      EncoderParameter epMultiFrame = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.MultiFrame); 
      ep.Param[0] = epMultiFrame; 
      MasterBitmap.SelectActiveFrame(dimension, start - 1); 
      MasterBitmap.Save(outputFileName, codecInfo, ep);//create master document 

      //FrameDimensionPage Encoding format 
      EncoderParameter epFrameDimensionPage = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.FrameDimensionPage); 
      ep.Param[0] = epFrameDimensionPage; 

      for (int i = start; i < end; i++) 
      { 
       imageAdd.SelectActiveFrame(dimension, i);//select next frame 
       MasterBitmap.SaveAdd(new Bitmap(imageAdd), ep);//add it to the master 
      } 

      //Flush Encoding format 
      EncoderParameter epFlush = new EncoderParameter(System.Drawing.Imaging.Encoder.SaveFlag, (long)EncoderValue.Flush); 
      ep.Param[0] = epFlush; 
      MasterBitmap.SaveAdd(ep); //flush the file     
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 
} 
4

tema de ayuda. Gracias por la info. Tuve la necesidad de unir una imagen multipágina de una matriz de cadenas codificadas en base64. Esto es lo que armé basado en la información en este hilo. No entiendo muy bien por qué tengo que crear una secuencia de memoria con el formato de imagen especificado explícitamente, pero esto es lo que terminó funcionando, si hay una mejor manera de lidiar con esto, por favor hágamelo saber. gracias

/// <summary> 
    /// Takes in an array of base64 encoded strings and creates a multipage tiff. 
    /// </summary> 
    /// <param name="sOutFile">file to be generated</param> 
    /// <param name="pagesbase64Array"></param> 
    private void SaevAsMultiPageTiff(string sOutFile, string[] pagesbase64Array) 
    { 
     System.Drawing.Imaging.Encoder encoder = System.Drawing.Imaging.Encoder.SaveFlag; 
     ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff"); 
     EncoderParameters encoderParameters = new EncoderParameters(1); 
     encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame); 

     Bitmap firstImage = null; 
     try 
     { 

      using (MemoryStream ms1 = new MemoryStream()) 
      { 
       using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[0]))) 
       { 
        Image.FromStream(ms).Save(ms1, ImageFormat.Tiff); 
        firstImage = (Bitmap)Image.FromStream(ms1); 
       } 
       // Save the first frame of the multi page tiff 
       firstImage.Save(sOutFile, encoderInfo, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called 
      } 


      encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage); 

      Bitmap imagePage; 
      // Add the remining images to the tiff 
      for (int i = 1; i < pagesbase64Array.Length; i++) 
      { 

       using (MemoryStream ms1 = new MemoryStream()) 
       { 
        using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(pagesbase64Array[i]))) 
        { 
         Image.FromStream(ms).Save(ms1, ImageFormat.Tiff); 
         imagePage = (Bitmap)Image.FromStream(ms1); 
        } 

        firstImage.SaveAdd(imagePage, encoderParameters); //throws Generic GDI+ error if the memory streams are not open when this is called 
       } 
      } 

     } 
     catch (Exception) 
     { 
      //ensure the errors are not missed while allowing for flush in finally block so files dont get locked up. 
      throw; 
     } 
     finally 
     { 
      // Close out the file 
      encoderParameters.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush); 
      firstImage.SaveAdd(encoderParameters); 
     } 
    } 
Cuestiones relacionadas