/// <summary>
		/// Save media to stream.
		/// </summary>
		/// <param name="stream">
		/// A <see cref="IO.Stream"/> which stores the media data.
		/// </param>
		/// <param name="image">
		/// A <see cref="Image"/> holding the data to be stored.
		/// </param>
		/// <param name="format">
		/// A <see cref="String"/> that specify the media format to used for saving <paramref name="image"/>.
		/// </param>
		/// <param name="criteria">
		/// A <see cref="MediaCodecCriteria"/> that specify parameters for loading an image stream.
		/// </param>
		/// <exception cref="ArgumentNullException">
		/// Exception thrown if <paramref name="stream"/>, <paramref name="image"/> or <paramref name="criteria"/> is null.
		/// </exception>
		public void Save(Stream stream, Image image, string format, MediaCodecCriteria criteria)
		{
			Bitmap iBitmap;
			System.Drawing.Imaging.ImageFormat iBitmapFormat;
			System.Drawing.Imaging.PixelFormat iBitmapPixelFormat;
			int iBitmapFlags;

			ConvertImageFormat(format, out iBitmapFormat);
			ConvertPixelFormat(image.PixelLayout, out iBitmapPixelFormat, out iBitmapFlags);

			// Obtain source and destination data pointers
			using (iBitmap = new Bitmap((int)image.Width, (int)image.Height, iBitmapPixelFormat)) {
				BitmapData iBitmapData = null;
				IntPtr imageData = image.ImageBuffer;

				try {
					iBitmapData = iBitmap.LockBits(new System.Drawing.Rectangle(0, 0, iBitmap.Width, iBitmap.Height), ImageLockMode.ReadOnly, iBitmap.PixelFormat);

					// Copy Image data dst Bitmap
					unsafe {
						byte* hImageDataPtr = (byte*)imageData.ToPointer();
						byte* iBitmapDataPtr = (byte*)iBitmapData.Scan0.ToPointer();
						uint hImageDataStride = image.Stride;
						uint iBitmapDataStride = (uint)iBitmapData.Stride;
						
						// .NET Image Library stores bitmap scan line data in memory padded dst 4 bytes boundaries
						// .NET Image Library expect a bottom up image, so invert the scan line order

						iBitmapDataPtr = iBitmapDataPtr + ((image.Height-1) * iBitmapDataStride);

						for (uint line = 0; line < image.Height; line++, hImageDataPtr += hImageDataStride, iBitmapDataPtr -= iBitmapDataStride)
							Memory.MemoryCopy(iBitmapDataPtr, hImageDataPtr, hImageDataStride);
					}
				} finally {
					if (iBitmapData != null)
						iBitmap.UnlockBits(iBitmapData);
				}

				// Save image with the specified format
				ImageCodecInfo encoderInfo = Array.Find(ImageCodecInfo.GetImageEncoders(), delegate(ImageCodecInfo item) {
					return (item.FormatID == iBitmapFormat.Guid);
				});

				EncoderParameters encoderParams = null;

				try {
					EncoderParameters encoderInfoParamList = iBitmap.GetEncoderParameterList(encoderInfo.Clsid);
					EncoderParameter[] encoderInfoParams = encoderInfoParamList != null ? encoderInfoParamList.Param : null;
					bool supportQuality = false;
					int paramsCount = 0;

					if (encoderInfoParams != null) {
						Array.ForEach(encoderInfoParams, delegate(EncoderParameter item) {
							if (item.Encoder.Guid == Encoder.Quality.Guid) {
								supportQuality = true;
								paramsCount++;
							}
						});
					}

					encoderParams = new EncoderParameters(paramsCount);

					paramsCount = 0;
					if (supportQuality)
						encoderParams.Param[paramsCount++] = new EncoderParameter(Encoder.Quality, 100);
				} catch (Exception) {
					// Encoder does not support parameters
				}

				iBitmap.Save(stream, encoderInfo, encoderParams);
			}
		}
Example #2
0
 private static EncoderParameter GetImageEncoderParameter(Bitmap source, ImageFormat format, Encoder encoder)
 {
     EncoderParameters enParams = source.GetEncoderParameterList(GetImageEncoder(format).Clsid);
     return GetImageEncoderParameter(enParams, encoder);
 }