// Save a JPEG image to the specified stream. public static void Save(Stream stream, Image image) { // Determine if we actually have the JPEG library. if(!JpegLib.JpegLibraryPresent()) { throw new FormatException("libjpeg is not available"); } // Create the compression object. JpegLib.jpeg_compress_struct cinfo; cinfo = new JpegLib.jpeg_compress_struct(); cinfo.err = JpegLib.CreateErrorHandler(); JpegLib.jpeg_create_compress(ref cinfo); // Initialize the destination manager. JpegLib.StreamToDestinationManager(ref cinfo, stream); // Get the frame to be written. Frame frame = image.GetFrame(0); // Set the JPEG compression parameters. cinfo.image_width = (UInt)(frame.Width); cinfo.image_height = (UInt)(frame.Height); cinfo.input_components = (Int)3; cinfo.in_color_space = JpegLib.J_COLOR_SPACE.JCS_RGB; JpegLib.jpeg_set_defaults(ref cinfo); // Start the compression process. JpegLib.jpeg_start_compress(ref cinfo, (Int)1); // Write the scanlines to the image. int posn, width, offset, stride; width = frame.Width; stride = frame.Stride; byte[] data = frame.Data; PixelFormat format = frame.PixelFormat; IntPtr buf = Marshal.AllocHGlobal(width * 3); byte *pbuf = (byte *)buf; while(((int)(cinfo.next_scanline)) < ((int)(cinfo.image_height))) { // Convert the source scanline into the JCS_RGB format. offset = ((int)(cinfo.next_scanline)) * stride; switch(format) { case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppArgb1555: { Rgb555(data, offset, width, pbuf); } break; case PixelFormat.Format16bppRgb565: { Rgb565(data, offset, width, pbuf); } break; case PixelFormat.Format24bppRgb: { Rgb24bpp(data, offset, width, pbuf); } break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: { Rgb32bpp(data, offset, width, pbuf); } break; case PixelFormat.Format1bppIndexed: { Rgb1bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format4bppIndexed: { Rgb4bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format8bppIndexed: { Rgb8bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format16bppGrayScale: { GrayScale16bpp(data, offset, width, pbuf); } break; case PixelFormat.Format48bppRgb: { Rgb48bpp(data, offset, width, pbuf); } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { Rgb64bpp(data, offset, width, pbuf); } break; } // Write the scanline to the buffer. JpegLib.jpeg_write_scanlines (ref cinfo, ref buf, (UInt)1); } Marshal.FreeHGlobal(buf); // Finish the compression process. JpegLib.jpeg_finish_compress(ref cinfo); // Clean everything up. JpegLib.FreeDestinationManager(ref cinfo); JpegLib.jpeg_destroy_compress(ref cinfo); JpegLib.FreeErrorHandler(cinfo.err); }
// Save a JPEG image to the specified stream. public static void Save(Stream stream, Image image) { // Determine if we actually have the JPEG library. if (!JpegLib.JpegLibraryPresent()) { throw new FormatException("libjpeg is not available"); } // Create the compression object. JpegLib.jpeg_compress_struct cinfo; cinfo = new JpegLib.jpeg_compress_struct(); cinfo.err = JpegLib.CreateErrorHandler(); JpegLib.jpeg_create_compress(ref cinfo); // Initialize the destination manager. JpegLib.StreamToDestinationManager(ref cinfo, stream); // Get the frame to be written. Frame frame = image.GetFrame(0); // Set the JPEG compression parameters. cinfo.image_width = (UInt)(frame.Width); cinfo.image_height = (UInt)(frame.Height); cinfo.input_components = (Int)3; cinfo.in_color_space = JpegLib.J_COLOR_SPACE.JCS_RGB; JpegLib.jpeg_set_defaults(ref cinfo); // Start the compression process. JpegLib.jpeg_start_compress(ref cinfo, (Int)1); // Write the scanlines to the image. int posn, width, offset, stride; width = frame.Width; stride = frame.Stride; byte[] data = frame.Data; PixelFormat format = frame.PixelFormat; IntPtr buf = Marshal.AllocHGlobal(width * 3); byte * pbuf = (byte *)buf; while (((int)(cinfo.next_scanline)) < ((int)(cinfo.image_height))) { // Convert the source scanline into the JCS_RGB format. offset = ((int)(cinfo.next_scanline)) * stride; switch (format) { case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppArgb1555: { Rgb555(data, offset, width, pbuf); } break; case PixelFormat.Format16bppRgb565: { Rgb565(data, offset, width, pbuf); } break; case PixelFormat.Format24bppRgb: { Rgb24bpp(data, offset, width, pbuf); } break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: { Rgb32bpp(data, offset, width, pbuf); } break; case PixelFormat.Format1bppIndexed: { Rgb1bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format4bppIndexed: { Rgb4bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format8bppIndexed: { Rgb8bpp(data, offset, width, pbuf, frame.Palette); } break; case PixelFormat.Format16bppGrayScale: { GrayScale16bpp(data, offset, width, pbuf); } break; case PixelFormat.Format48bppRgb: { Rgb48bpp(data, offset, width, pbuf); } break; case PixelFormat.Format64bppPArgb: case PixelFormat.Format64bppArgb: { Rgb64bpp(data, offset, width, pbuf); } break; } // Write the scanline to the buffer. JpegLib.jpeg_write_scanlines (ref cinfo, ref buf, (UInt)1); } Marshal.FreeHGlobal(buf); // Finish the compression process. JpegLib.jpeg_finish_compress(ref cinfo); // Clean everything up. JpegLib.FreeDestinationManager(ref cinfo); JpegLib.jpeg_destroy_compress(ref cinfo); JpegLib.FreeErrorHandler(cinfo.err); }