需求:从播放器上截取出当前帧,提交到服务器/或吐给javascript
1、从当前的MediaElement上创建WriteableBitmap
WriteableBitmap bitmap = new WriteableBitmap(this.Player, null);
2、从WriteableBitmap编码成jpg格式
public static void SavePicToStream(WriteableBitmap bitmap, Stream stream)
{
int width = bitmap.PixelWidth;
int height = bitmap.PixelHeight;
int bands = 3;
byte[][,] raster = new byte[bands][,]; //用来保存bitmap中每个像素点的RGB分量的数组
for (int i = 0; i < bands; i++)
{
raster[i] = new byte[width, height];
}
for (int row = 0; row < height; row++)
{
for (int column = 0; column < width; column++)
{
int pixel = bitmap.Pixels[width * row + column];
raster[0][column, row] = (byte)(pixel >> 16); //R
raster[1][column, row] = (byte)(pixel >> 8); //G
raster[2][column, row] = (byte)pixel; //B
}
}
FluxJpeg.Core.ColorModel model = new FluxJpeg.Core.ColorModel { colorspace = FluxJpeg.Core.ColorSpace.RGB };
FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster);
FluxJpeg.Core.Encoder.JpegEncoder encoder = new FluxJpeg.Core.Encoder.JpegEncoder(img, 100, stream);
encoder.Encode();
}
3、转化为base64编码传输
public string GetCurrentImageBase64String()
{
var stream = new MemoryStream();
Tools.SavePicToStream(this.GetCurrentImage(), stream);
stream.Seek(0, SeekOrigin.Begin);
var binaryData = new Byte[stream.Length];
long bytesRead = stream.Read(binaryData, 0, (int)stream.Length);
string t = Convert.ToBase64String(binaryData);
return t;
}
注意:视频文件和XAP必须在同一个域,否则将出现WriteableBitmap的Pixels受保护,无法读。(出于版权保护的原因)
微软MSDN给出的解释如下:
受保护的内容
如果使用跨域内容构造 WriteableBitmap,则 WriteableBitmap 类具有安全模式,该模式限制对 Pixels 数组的访问。 例如,使用引用来自另一个域的 URL 的BitmapImage 构造的 WriteableBitmap 不允许访问其 Pixels 数组。 该限制扩展到任何为设置其部分或所有内容而使用 URL 派生属性的 UI 元素。 具体而言,此限制适用于“从 MediaElement 抓取正在运行的视频帧”方案。 如果 MediaElement.Source 引用另一个域中的视频文件,那么通过引用 MediaElement 作为元素源创建的 WriteableBitmap 限制对 Pixels 数组的访问。
即使创建自受保护的内容,也仍可以访问 WriteableBitmap 的 PixelHeight 和 PixelWidth 属性。 此信息可用于确定内容的固有大小,例如用于保留其大小调整到源的 MediaElement。