/// <summary>Converts a bitmap to a Tiff with a specific compression</summary> /// /// <param name="inputBmp">Bitmap to convert</param> /// <param name="compression">The compression to use on the TIFF file output. Be warned that the CCITT3, CCITT4, /// and RLE compression options are only applicable to TIFFs using a palette index color depth /// (that is, 1, 4, or 8 bpp). Using any of these compression schemes with 24 or 32-bit /// TIFFs will throw an exception from the bowels of GDI+</param> /// /// <returns>A new bitmap object containing the input bitmap converted. /// If the destination format and the target format are the same, returns /// a clone of the destination bitmap.</returns> public static Bitmap ConvertBitmapToTiff(Bitmap inputBmp, TiffCompressionEnum compression) { //If the dest format matches the source format and quality/bpp not changing, just clone if (inputBmp.RawFormat.Equals(ImageFormat.Tiff) && compression == TiffCompressionEnum.Unspecified) { return((Bitmap)inputBmp.Clone()); } if (compression == TiffCompressionEnum.Unspecified) { //None of the params are chaning; use the general purpose converter return(ConvertBitmap(inputBmp, ImageFormat.Tiff)); } //Create an in-memory stream which will be used to save //the converted image Stream imgStream = new MemoryStream(); //Get the ImageCodecInfo for the desired target format ImageCodecInfo destCodec = FindCodecForType(MimeTypeFromImageFormat(ImageFormat.Tiff)); if (destCodec == null) { //No codec available for that format throw new ArgumentException("The requested format " + MimeTypeFromImageFormat(ImageFormat.Tiff) + " does not have an available codec installed", "destFormat"); } //Create an EncoderParameters collection to contain the //parameters that control the dest format's encoder var destEncParams = new EncoderParameters(1); //set the compression parameter EncoderValue compressionValue; switch (compression) { case TiffCompressionEnum.CCITT3: compressionValue = EncoderValue.CompressionCCITT3; break; case TiffCompressionEnum.CCITT4: compressionValue = EncoderValue.CompressionCCITT4; break; case TiffCompressionEnum.LZW: compressionValue = EncoderValue.CompressionLZW; break; case TiffCompressionEnum.RLE: compressionValue = EncoderValue.CompressionRle; break; default: compressionValue = EncoderValue.CompressionNone; break; } var compressionParam = new EncoderParameter(Encoder.Compression, (long)compressionValue); destEncParams.Param[0] = compressionParam; //Save w/ the selected codec and encoder parameters inputBmp.Save(imgStream, destCodec, destEncParams); //At this point, imgStream contains the binary form of the //bitmap in the target format. All that remains is to load it //into a new bitmap object var destBitmap = new Bitmap(imgStream); //Free the stream //imgStream.Close(); //For some reason, the above causes unhandled GDI+ exceptions //when destBitmap.Save is called. Perhaps the bitmap object reads //from the stream asynchronously? return(destBitmap); }
/// <summary>Converts a bitmap to a Tiff with a specific compression</summary> /// /// <param name="inputBmp">Bitmap to convert</param> /// <param name="compression">The compression to use on the TIFF file output. Be warned that the CCITT3, CCITT4, /// and RLE compression options are only applicable to TIFFs using a palette index color depth /// (that is, 1, 4, or 8 bpp). Using any of these compression schemes with 24 or 32-bit /// TIFFs will throw an exception from the bowels of GDI+</param> /// /// <returns>A new bitmap object containing the input bitmap converted. /// If the destination format and the target format are the same, returns /// a clone of the destination bitmap.</returns> public static Bitmap ConvertBitmapToTiff(Bitmap inputBmp, TiffCompressionEnum compression) { //If the dest format matches the source format and quality/bpp not changing, just clone if (inputBmp.RawFormat.Equals(ImageFormat.Tiff) && compression == TiffCompressionEnum.Unspecified) { return(Bitmap)inputBmp.Clone(); } if (compression == TiffCompressionEnum.Unspecified) { //None of the params are chaning; use the general purpose converter return ConvertBitmap(inputBmp, ImageFormat.Tiff); } //Create an in-memory stream which will be used to save //the converted image System.IO.Stream imgStream = new System.IO.MemoryStream(); //Get the ImageCodecInfo for the desired target format ImageCodecInfo destCodec = FindCodecForType(MimeTypeFromImageFormat(ImageFormat.Tiff)); if (destCodec == null) { //No codec available for that format throw new ArgumentException("The requested format " + MimeTypeFromImageFormat(ImageFormat.Tiff) + " does not have an available codec installed", "destFormat"); } //Create an EncoderParameters collection to contain the //parameters that control the dest format's encoder EncoderParameters destEncParams = new EncoderParameters(1); //set the compression parameter EncoderValue compressionValue; switch (compression) { case TiffCompressionEnum.CCITT3: compressionValue = EncoderValue.CompressionCCITT3; break; case TiffCompressionEnum.CCITT4: compressionValue = EncoderValue.CompressionCCITT4; break; case TiffCompressionEnum.LZW: compressionValue = EncoderValue.CompressionLZW; break; case TiffCompressionEnum.RLE: compressionValue = EncoderValue.CompressionRle; break; default: compressionValue = EncoderValue.CompressionNone; break; } EncoderParameter compressionParam = new EncoderParameter(Encoder.Compression, (long)compressionValue); destEncParams.Param[0] = compressionParam; //Save w/ the selected codec and encoder parameters inputBmp.Save(imgStream, destCodec, destEncParams); //At this point, imgStream contains the binary form of the //bitmap in the target format. All that remains is to load it //into a new bitmap object Bitmap destBitmap = new Bitmap(imgStream); //Free the stream //imgStream.Close(); //For some reason, the above causes unhandled GDI+ exceptions //when destBitmap.Save is called. Perhaps the bitmap object reads //from the stream asynchronously? return destBitmap; }