public static Bitmap GetFrameFromVideo(string videoFile, double percentagePosition, out double streamLength, Size target)
{
if (videoFile == null)
throw new ArgumentNullException("videoFile");
if (percentagePosition > 1 || percentagePosition < 0)
throw new ArgumentOutOfRangeException("percentagePosition", percentagePosition, "Valid range is 0.0 .. 1.0");
if (target.Width % 4 != 0 || target.Height % 4 != 0)
throw new ArgumentException("Target size must be a multiple of 4", "target");
IMediaDet mediaDet = null;
try
{
_AMMediaType mediaType;
if (openVideoStream(videoFile, out mediaDet, out mediaType))
{
streamLength = mediaDet.StreamLength;
//calculates the REAL target size of our frame
if (target == Size.Empty)
target = getVideoSize(mediaType);
else
{
target = scaleToFit(target, getVideoSize(mediaType));
//ensures that the size is a multiple of 4 (required by the Bitmap constructor)
//************************************************************************************************************************
target.Width -= target.Width% 4;
target.Height -= target.Height % 4;
}
unsafe
{
Size s = getVideoSize(mediaType);
int bmpinfoheaderSize =40; //equals to sizeof(CommonClasses.BITMAPINFOHEADER);
//get size for buffer
int bufferSize = (((s.Width * s.Height) * 24) / 8)+ bmpinfoheaderSize; //equals to mediaDet.GetBitmapBits(0d, ref bufferSize, ref *buffer, target.Width, target.Height);
//allocates enough memory to store the frame
IntPtr frameBuffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(bufferSize);
byte* frameBuffer2 = (byte*)frameBuffer.ToPointer();
//gets bitmap, save in frameBuffer2
mediaDet.GetBitmapBits(streamLength * percentagePosition, ref bufferSize, ref *frameBuffer2, target.Width, target.Height);
//now in buffer2 we have a BITMAPINFOHEADER structure followed by the DIB bits
Bitmap bmp = new Bitmap(target.Width, target.Height, target.Width *3, System.Drawing.Imaging.PixelFormat.Format24bppRgb, new IntPtr(frameBuffer2 + bmpinfoheaderSize));
bmp.RotateFlip(RotateFlipType.Rotate180FlipX);
System.Runtime.InteropServices.Marshal.FreeHGlobal(frameBuffer);
//*************************************************************************************************************************************
//************************************************************************************************************************************
//bmp.SetResolution(600, 600);
return bmp ;
}
}
}
catch (COMException ex)
{
throw new InvalidVideoFileException(getErrorMsg((uint)ex.ErrorCode), ex);
}
finally
{
if (mediaDet != null)
Marshal.ReleaseComObject(mediaDet);
}
throw new InvalidVideoFileException("No video stream was found");
}
|