EasyPlayerPro Windows播放器本地快照抓拍截图功能实现方法
2017-12-25 14:04
711 查看
背景描述
作为一个播放器,截图功能必不可少; 下面主要记录一下截图功能的实现;实现流程
将解码后的帧进行格式转换(目标格式为RGB24);采用独立的线程进行截图处理;
截图可保存为BMP或JPG两种格式;
代码实现
#define _WIDTHBYTES(c) ((c+31)/32*4) // c = width * bpp int Snapshot2File(RENDER_FORMAT renderFormat, SNAPSHOT_IMAGE_T *pSnapshot, char *pbuf) { PBYTE pDest = NULL, pDest16 = NULL; INT nBpp; DWORD dwW, dwH, dwWB; int ret = 0; int image_format = pSnapshot->imageFormat; if (renderFormat == RENDER_FORMAT_YUY2) nBpp = 16; else if (renderFormat == RENDER_FORMAT_UYVY) nBpp = 16; else if (renderFormat == RENDER_FORMAT_X8R8G8B8) nBpp = 32; //ok else if (renderFormat == RENDER_FORMAT_A8R8G8B8) nBpp = 32; //ok else if (renderFormat == RENDER_FORMAT_RGB565) nBpp = 16; //ok else if (renderFormat == RENDER_FORMAT_RGB555) nBpp = 16; //ok else if (renderFormat == RENDER_FORMAT_RGB24_GDI) nBpp = 24; else return -1; //格式错误 dwW = pSnapshot->width; dwH = pSnapshot->height; dwWB = _WIDTHBYTES( dwW * nBpp ); if (image_format == 0x00) { //BMP int iFilenameLen = (int)strlen(pSnapshot->filename); if ( (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "bmp", 3)) && (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "BMP", 3)) && (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "Bmp", 3)) ) { if (pSnapshot->filename[iFilenameLen-4] == '.') { for (int i=iFilenameLen-1; i>0; i--) { if (pSnapshot->filename[i] == '.') { pSnapshot->filename[i] = '\0'; break; } else { pSnapshot->filename[i] = '\0'; } } } strcat(pSnapshot->filename, ".bmp"); } HANDLE hFile = CreateFile( pSnapshot->filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if( hFile == INVALID_HANDLE_VALUE ) return E_HANDLE; // SaveFile to BMP BITMAPFILEHEADER bfh = {0}; bfh.bfType = 0x4D42; bfh.bfSize = 0; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); if( nBpp == 16 ) { bfh.bfOffBits += sizeof(RGBQUAD) * 3; } else if( nBpp == 24 ) { bfh.bfOffBits += sizeof(RGBQUAD) * 1; } else if( nBpp == 32 ) { bfh.bfOffBits += sizeof(RGBQUAD) * 1; } DWORD dwWriteLength = sizeof(BITMAPFILEHEADER); DWORD dwWrittenLength = 0; WriteFile( hFile, (PVOID)&bfh, dwWriteLength, &dwWrittenLength, NULL ); BITMAPINFOHEADER bih = {0}; bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = dwW; bih.biHeight = -(INT)dwH; bih.biPlanes = 1; bih.biBitCount = nBpp; bih.biCompression = (nBpp == 16) ? BI_BITFIELDS : BI_RGB; bih.biSizeImage = dwWB * pSnapshot->height; bih.biXPelsPerMeter = 0; bih.biYPelsPerMeter = 0; bih.biClrUsed = 0; bih.biClrImportant = 0; dwWriteLength = sizeof(BITMAPINFOHEADER); WriteFile( hFile, (PVOID)&bih, dwWriteLength, &dwWrittenLength, NULL ); if( nBpp == 16 ) { DWORD argbQuad[3] = {0}; if (renderFormat == RENDER_FORMAT_RGB565) { argbQuad[0] = 0x00F800; // Red mask argbQuad[1] = 0x0007E0; // Green mask argbQuad[2] = 0x00001F; // Blue mask } else { argbQuad[0] = 0x007C00; // Red mask argbQuad[1] = 0x0003E0; // Green mask argbQuad[2] = 0x00001F; // Blue mask } dwWriteLength = sizeof(argbQuad); WriteFile( hFile, (PVOID)&argbQuad[0], dwWriteLength, &dwWrittenLength, NULL ); } else if( nBpp == 24 ) { DWORD rgbQuad = 0; dwWriteLength = sizeof(rgbQuad); WriteFile( hFile, (PVOID)&rgbQuad, dwWriteLength, &dwWrittenLength, NULL ); } else if( nBpp == 32 ) { DWORD rgbQuad = 0; dwWriteLength = sizeof(rgbQuad); WriteFile( hFile, (PVOID)&rgbQuad, dwWriteLength, &dwWrittenLength, NULL ); } dwWriteLength = dwWB * pSnapshot->height; WriteFile( hFile, (PVOID)pbuf, dwWriteLength, &dwWrittenLength, NULL ); CloseHandle( hFile ); if (dwWrittenLength < 1) { DeleteFile(pSnapshot->filename); } } else if (image_format == 0x01) { //JPG int iFilenameLen = (int)strlen(pSnapshot->filename); if ( (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "jpg", 3)) && (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "JPG", 3)) && (0 != memcmp(pSnapshot->filename+iFilenameLen-3, "Jpg", 3)) ) { if (pSnapshot->filename[iFilenameLen-4] == '.') { for (int i=iFilenameLen-1; i>0; i--) { if (pSnapshot->filename[i] == '.') { pSnapshot->filename[i] = '\0'; break; } else { pSnapshot->filename[i] = '\0'; } } } strcat(pSnapshot->filename, ".jpg"); } BOOL bres = TRUE; IJLERR jerr; DWORD dibPadBytes; JPEG_CORE_PROPERTIES jcprops; __try { jerr = ijlInit(&jcprops); if (IJL_OK != jerr) { bres = FALSE; __leave; } dibPadBytes = IJL_DIB_PAD_BYTES(dwW, 3); jcprops.DIBWidth = dwW; jcprops.DIBHeight = dwH; jcprops.DIBBytes = (unsigned char*)pbuf;//reinterpret_cast<BYTE *>(&pbi->bmiHeader) + sizeof(BITMAPINFOHEADER); jcprops.DIBPadBytes = dibPadBytes; jcprops.DIBChannels = 3; jcprops.DIBColor = IJL_BGR; jcprops.JPGFile = const_cast<LPSTR>(pSnapshot->filename); jcprops.JPGWidth = dwW; jcprops.JPGHeight = dwH; jcprops.JPGChannels = 3; jcprops.JPGColor = IJL_YCBCR; jcprops.JPGSubsampling = IJL_411; jcprops.jquality = 95; jerr = ijlWrite(&jcprops, IJL_JFILE_WRITEWHOLEIMAGE); if (IJL_OK != jerr) { if (IJL_FILE_ERROR == jerr) { } ret = jerr; bres = FALSE; if (ret == -23) { DeleteFile(pSnapshot->filename); } } } __finally { ijlFree(&jcprops); } } if (NULL != pDest) { delete []pDest; pDest = NULL; } return ret; }
关于EasyPlayerPro
EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放、倍数播放等多种功能特性,核心基于ffmpeg,稳定、高效、可靠、可控,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!获取更多信息
邮件:support@easydarwin.orgEasyDarwin开源流媒体服务器:www.EasyDarwin.org
EasyDSS商用流媒体解决方案:www.EasyDSS.com
EasyNVR无插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2017
相关文章推荐
- EasyPlayerPro Windows播放器本地快照抓拍截图功能实现方法
- EasyPlayerPro Windows播放器实时流进行本地缓冲区即时回放功能实现
- EasyPlayerPro Windows播放器实时流进行本地缓冲区即时回放功能实现
- EasyPlayerPro windows播放器本地音频播放音量控制实现
- EasyPlayerPro windows播放器本地配置文件配置方法介绍
- EasyPlayerPro windows播放器本地音频播放音量控制实现
- EasyPlayerPro windows播放器本地配置文件配置方法介绍
- EasyPlayerPro windows播放器之多窗口播放音量控制方法
- EasyPlayerPro-win截图功能实现
- EasyPlayerPro windows播放器之多窗口播放音量控制方法
- 在EasyPlayerPro上实现一键平稳切换视频源的功能
- EasyPlayer RTSP Windows播放器OSD字幕叠加接口方法和使用效果全解析
- EasyPlayerPro基于FFMPEG实现播放同时进行录像的功能
- EasyPlayerPro-win本地音频采集实现
- EasyPlayerPro-win即时回放功能实现
- EasyPlayerPro windows播放器在播放RTMP视频显示重复异常问题解决
- EasyPlayerPro windows播放器在播放RTMP视频显示重复异常问题解决
- EasyPlayerPro(Windows)流媒体播放器功能介绍及应用场景
- EasyPlayerPro(Windows)开发系列之快放慢放的实现
- EasyPlayerPro-win电子放大功能实现