windows下使用ffmpeg + DDRAW 截屏,并保存为图片
2012-10-31 17:14
387 查看
不清楚原理的看上篇文章《用DirectDraw实现屏幕截图》。
下面直接贴代码
下面直接贴代码
#include <windows.h> #include <stdio.h> #include "ddraw.h" extern "C"{ #include "libavcodec/avcodec.h" #include "libswscale/swscale.h" } void save_bmp(unsigned char * data,int data_size,int w,int h,FILE * out) { // 位图文件头 BITMAPFILEHEADER bmpheader; BITMAPINFO bmpinfo; int bit = 24; bmpheader.bfType = ('M' <<8)|'B'; bmpheader.bfReserved1 = 0; bmpheader.bfReserved2 = 0; bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); bmpheader.bfSize = bmpheader.bfOffBits + w*h*bit/8; bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpinfo.bmiHeader.biWidth = w; bmpinfo.bmiHeader.biHeight = 0-h; bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = bit; bmpinfo.bmiHeader.biCompression = BI_RGB; bmpinfo.bmiHeader.biSizeImage = 0; bmpinfo.bmiHeader.biXPelsPerMeter = 100; bmpinfo.bmiHeader.biYPelsPerMeter = 100; bmpinfo.bmiHeader.biClrUsed = 0; bmpinfo.bmiHeader.biClrImportant = 0; fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,out); fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,out); fwrite(data,data_size,1,out); } int main() { LPDIRECTDRAW7 lpddraw = NULL,ddraw2; // DDraw 对象 DDSURFACEDESC2 ddsd;// ddraw 显示表面 描述结构 LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // ddraw 主显示表面 LPDIRECTDRAWSURFACE7 lpddsoffscr = NULL; // ddraw 离屏表面 if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpddraw, IID_IDirectDraw7, NULL))) { printf("DDraw create failed.\n"); return -1; } if (FAILED( lpddraw ->QueryInterface(IID_IDirectDraw7,(LPVOID *)&ddraw2))) { printf("Couldn't query the interface.\n"); lpddraw ->Release(); return -1; } // 窗口模式(设置协作级别) lpddraw->SetCooperativeLevel( NULL, DDSCL_NORMAL | DDSCL_ALLOWREBOOT ); // 初始化 ddsd ZeroMemory(&ddsd,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); //指定该结构所占的字节数 ddsd.dwFlags = DDSD_CAPS/*使ddsCaps成员有效 *//*|DDSD_BACKBUFFERCOUNT打开后备缓冲标志*/; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE/*|DDSCAPS_COMPLEX|DDSCAPS_FLIP创建一个带后备缓冲的主表面*/; // 创建主显示表面 if (FAILED(lpddraw->CreateSurface(&ddsd, &lpddsprimary, NULL))) { printf("Create primary Surface failed.\n"); lpddraw ->Release(); return -1; } // 锁定surface HRESULT ddRval = DD_OK; do { ddRval = lpddsprimary->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_WRITEONLY,NULL); } while(ddRval == DDERR_WASSTILLDRAWING); printf("Lock Success.\n"); // 获取surface信息 DWORD dwBitDepth = ddsd.ddpfPixelFormat.dwRGBBitCount; DWORD dwWidth = ddsd.dwWidth; DWORD dwHeight = ddsd.dwHeight; LONG lPitch = ddsd.lPitch; BYTE *lpData = (BYTE *)ddsd.lpSurface;//实际数据 DWORD dwRBitMask = ddsd.ddpfPixelFormat.dwRBitMask; DWORD dwGBitMask = ddsd.ddpfPixelFormat.dwGBitMask; DWORD dwBBitMask = ddsd.ddpfPixelFormat.dwBBitMask; int len = dwWidth*dwHeight*dwBitDepth/8; BYTE * lpBuf = (BYTE*)malloc(len);//用于存储surface实际数据 memset(lpBuf,0,len); memcpy(lpBuf,lpData,len); //解锁surface lpddsprimary->Unlock(0); //转换和缩放图片 int dst_img_width = 400; int dst_img_height = 300; struct SwsContext * pSwsCtx = sws_getContext( dwWidth,dwHeight,PIX_FMT_BGRA, dst_img_width,dst_img_height,PIX_FMT_BGR24, SWS_BILINEAR, NULL,NULL,NULL); //先将图片转换为BGR24视频帧 uint8_t * buffer = NULL; AVFrame * rgb_frame = avcodec_alloc_frame(); buffer = (unsigned char *)av_malloc(avpicture_get_size(PIX_FMT_BGR24,dst_img_width,dst_img_height)); avpicture_fill((AVPicture*)rgb_frame,(uint8_t *)buffer,PIX_FMT_BGR24,dst_img_width,dst_img_height); uint8_t *data[4] = {lpBuf,0,0,0}; int linesize[4] = {dwWidth*dwBitDepth/8,0,0,0}; //缩放图片 sws_scale(pSwsCtx,data,linesize,0,dwHeight,rgb_frame ->data,rgb_frame ->linesize); //释放资源 free(lpBuf); sws_freeContext(pSwsCtx); //写文件 FILE * fp = fopen("test.bmp","wb"); save_bmp(rgb_frame ->data[0],rgb_frame ->linesize[0]*dst_img_height,dst_img_width,dst_img_height,fp); fclose(fp); av_free(rgb_frame); av_free(buffer); //释放资源 lpddsprimary ->Release(); lpddraw ->Release(); return 0; }
相关文章推荐
- 从零开始学习音视频编程技术(五) 使用FFMPEG解码视频之保存成图片
- [转载] ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
- FFMPEG教程1_解码后保存图片(使用2014年新SDK重新整理编译通过)
- ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
- unity3D调用外接摄像头,保存图片、不使用截屏方式
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
- QT在windows下实现截屏操作并保存为png图片
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
- Unity使用Windows弹窗保存图片
- ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
- 从零开始学习音视频编程技术(五) 使用FFMPEG解码视频之保存成图片
- ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
- ffmpeg Windows下采集摄像头一帧数据,并保存为bmp图片
- ffmpeg将视频每帧画面保存为PPM格式图片,使用最新的ffmpeg官网15-7-2日更新的版本
- windows下使用ffmpeg进行视频转码,图片拉取的Java测试代码
- windows下使用MinGW+msys编译ffmpeg
- 使用adb命令对手机进行截屏保存到电脑,SDCard
- windows下使用MinGW+msys编译ffmpeg
- Python---对html文件内容进行搜索取出特定URL地址字符串,保存成列表,并使用每个url下载图片,并保存到硬盘上,使用正则re