/// <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); } }
private static EncoderParameter GetImageEncoderParameter(Bitmap source, ImageFormat format, Encoder encoder) { EncoderParameters enParams = source.GetEncoderParameterList(GetImageEncoder(format).Clsid); return GetImageEncoderParameter(enParams, encoder); }