最近了解了一下ffmpeg方面的内容,针对ffmpeg解帧,并保存图片的方法,找了个很好用的,就先记下了。内容出处:https://xiva.iteye.com/blog/1993599

首先下载ffmpeg的开发包以及依赖包,当然也可以下载源码。

http://ffmpeg.zeranoe.com/builds/

其次为了编码为JPEG格式的图片,需要下载Independent JPEG Group

http://www.ijg.org/files/jpegsr9.zip

下载IJG后,需要对源码进行编译,生成静态库,

本人是使用VS2010编译的,其中含有install.txt文件讲述了怎么讲make file文件转换为VS工程文件,使用下面命令可以做到:

NMAKE /f makefile.vc  setup-v10

其中会遇到windows环境变量中没有NMAKE 的问题,还有Win32.Mak找不到的问题。

1、找到nmake.exe配一下环境变量

2、在makefile.vc文件中找到Win32.Mak,将相应路径添加上,如:

!include <C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\Win32.Mak>

如果嫌Independent JPEG Group编译麻烦,我倒是有个编译好的:https://download.csdn.net/download/summer_9527/10937443(Vs2008)

https://download.csdn.net/download/summer_9527/11862213(VS2015)

而且这个玩意还能bmp图片转jpg格式,具体内容:https://blog.csdn.net/y601500359/article/details/80401958 没错,我就是大自然的搬运工

具体代码如下

#include <math.h>
#include <windows.h>  #include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>  #include <jpeglib.h>
#include <setjmp.h>  #define inline __inline
#define snprintf _snprintf  #define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096  #pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "avcodec.lib")
#pragma comment (lib, "avdevice.lib")
#pragma comment (lib, "avfilter.lib")
#pragma comment (lib, "avformat.lib")
#pragma comment (lib, "avutil.lib")
#pragma comment (lib, "swresample.lib")
#pragma comment (lib, "swscale.lib")  #pragma comment(lib, "jpeg.lib")  static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);  static void yuv420p_save(AVFrame *pFrame, int width, int height, int iFrame);  static void bmp_save(AVFrame *pFrame, int width, int height, int iFrame);  static void saveFrame_jpg(uint8_t *pRGBBuffer, int iFrame, int width, int height);  int main(int argc, char **argv)
{  AVFormatContext *pFormatCtx = NULL;  char            *fileName = "E:\\aa.rm";  int             i,videoStream;  AVCodecContext  *pCodecCtx;  AVCodec         *pCodec;  AVFrame         *pFrame;  AVFrame         *pFrameRGB;  int             numBytes;  uint8_t         *buffer;  AVPacket        packet;  int             frameFinished;  struct SwsContext *img_convert_ctx = NULL;  av_register_all();  if(avformat_open_input(&pFormatCtx, fileName, NULL, NULL)!=0)  {  printf("can not open");  return -1;  }  if(avformat_find_stream_info(pFormatCtx, NULL) < 0)  {  printf("can not find");  return -1;  }  av_dump_format(pFormatCtx, -1, fileName, 0);  videoStream = -1;  for (i=0;i<pFormatCtx->nb_streams;i++)  {  if( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)  {  videoStream = i;  break;  }  }  if ( videoStream == -1 )  {  printf("not find videoStream");  return -1;  }  pCodecCtx = pFormatCtx->streams[videoStream]->codec;  pCodec = avcodec_find_decoder(pCodecCtx->codec_id);  if ( pCodec == NULL )  {  return -1;  }  if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0 )  {  return -1;  }  pFrame = av_frame_alloc();  if( pFrame == NULL )  {  return -1;  }  pFrameRGB = av_frame_alloc();  if( pFrameRGB == NULL )  {  return -1;  }  numBytes = avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);  buffer = av_malloc(numBytes);  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);  img_convert_ctx = sws_getCachedContext(img_convert_ctx, pCodecCtx->width, pCodecCtx->height,  pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);  i = 0;  while( av_read_frame(pFormatCtx, &packet) >= 0 )  {  if( packet.stream_index == videoStream )  {  avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);  if ( frameFinished )  {  if (!img_convert_ctx )  {  fprintf(stderr, "Cannot initialize sws conversion context\n");  exit(1);  }  sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,  pFrameRGB->data, pFrameRGB->linesize);  if(i++<5)  {  //SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);  //yuv420p_save(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);  //bmp_save(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);  saveFrame_jpg(pFrameRGB->data[0], i, pCodecCtx->width, pCodecCtx->height);  }  }  }  if(i > 5)  {  break;  }  }  av_free_packet(&packet);  av_free(buffer);  av_free(pFrame);  av_free(pFrameRGB);  avcodec_close(pCodecCtx);  avformat_close_input(&pFormatCtx);  return 0;
}  static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
{  FILE *pFile;  char szFilename[32];  int y;  sprintf(szFilename, "frame%d.jpg", iFrame);  pFile = fopen(szFilename, "wb");  if( !pFile )  {  return;  }  fprintf(pFile, "P6\n%d %d\n255\n", width, height);  for ( y=0; y<height; y++ )  {  fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);  }  fclose(pFile);
}  static void yuv420p_save(AVFrame *pFrame, int width, int height, int iFrame)
{  int i = 0;  FILE *pFile;  char szFilename[32];  int height_half = height / 2, width_half = width / 2;  int y_wrap = pFrame->linesize[0];  int u_wrap = pFrame->linesize[1];  int v_wrap = pFrame->linesize[2];  unsigned char *y_buf = pFrame->data[0];  unsigned char *u_buf = pFrame->data[1];  unsigned char *v_buf = pFrame->data[2];  sprintf(szFilename, "frame%d.jpg", iFrame);  pFile = fopen(szFilename, "wb");  //save y  for (i = 0; i < height; i++)  fwrite(y_buf + i * y_wrap, 1, width, pFile);  fprintf(stderr, "===>save Y success\n");  //save u  for (i = 0; i < height_half; i++)  fwrite(u_buf + i * u_wrap, 1, width_half, pFile);  fprintf(stderr, "===>save U success\n");  //save v  for (i = 0; i < height_half; i++)  fwrite(v_buf + i * v_wrap, 1, width_half, pFile);  fprintf(stderr, "===>save V success\n");  fflush(pFile);  fclose(pFile);
}  static void bmp_save(AVFrame *pFrame, int width, int height, int iFrame)
{  BITMAPFILEHEADER bmpheader;  BITMAPINFO bmpinfo;  int y = 0;  FILE *pFile;  char szFilename[32];  unsigned char *y_buf = pFrame->data[0];  sprintf(szFilename, "frame%d.bmp", iFrame);  pFile = fopen(szFilename, "wb");  bmpheader.bfReserved1 = 0;  bmpheader.bfReserved2 = 0;  bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);  bmpheader.bfSize = bmpheader.bfOffBits + width*height*24/8;  bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  bmpinfo.bmiHeader.biWidth = width;  bmpinfo.bmiHeader.biHeight = -height;  bmpinfo.bmiHeader.biPlanes = 1;  bmpinfo.bmiHeader.biBitCount = 24;  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, pFile);  fwrite(&bmpinfo.bmiHeader, sizeof(BITMAPINFOHEADER), 1, pFile);  fwrite(pFrame->data[0], width*height*24/8, 1, pFile);  /*for(y=0; y<height; y++)  {  fwrite(pFrame->data[0] + y*pFrame->linesize[0], 1, width*3, pFile);  }*/  //fflush(pFile);  fclose(pFile);
}  static void saveFrame_jpg(uint8_t *pRGBBuffer, int iFrame, int width, int height)
{  struct jpeg_compress_struct cinfo;  struct jpeg_error_mgr jerr;  char szFilename[1024];  int row_stride;  FILE *fp;  JSAMPROW row_pointer[1];   // 一行位图  cinfo.err = jpeg_std_error(&jerr);  jpeg_create_compress(&cinfo);  sprintf(szFilename, "test%d.jpg", iFrame);//图片名字为视频名+号码  fp = fopen(szFilename, "wb");  if(fp == NULL)  return;  jpeg_stdio_dest(&cinfo, fp);  cinfo.image_width = width;    // 为图的宽和高,单位为像素   cinfo.image_height = height;  cinfo.input_components = 3;   // 在此为1,表示灰度图, 如果是彩色位图,则为3   cinfo.in_color_space = JCS_RGB; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像  jpeg_set_defaults(&cinfo);   jpeg_set_quality (&cinfo, 80, 1);  jpeg_start_compress(&cinfo, TRUE);  row_stride = cinfo.image_width * 3;//每一行的字节数,如果不是索引图,此处需要乘以3  // 对每一行进行压缩  while (cinfo.next_scanline < cinfo.image_height) {  row_pointer[0] = &(pRGBBuffer[cinfo.next_scanline * row_stride]);  jpeg_write_scanlines(&cinfo, row_pointer, 1);  }  jpeg_finish_compress(&cinfo);  jpeg_destroy_compress(&cinfo);  fclose(fp);
}  

采用FFmpeg解帧,并保存为JPG、BMP格式文件相关推荐

  1. ffmpeg获取rtsp h265_用FFmpeg将rtsp视频流保存成H264、h265文件

    ffmpeg:FFmpeg的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward,是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算 ...

  2. 小程序资源下载、解压、保存到本地及本地文件的使用

    小程序对资源存储有限一般10M,不要超过限制 思路解析:将资源保存到本地,首先 需要获取到 本地路径 ,然后将文件下载(下载前需要判断文件是否更新,第一次和更新则需要下载,如果存在之前的资源则将其删除 ...

  3. 解压zip、rar、gz格式文件

    rar解压版本:需要使用0.7,其他版本尝试了,不行,而且rar压缩的时候,也需要指定rar4,高版本不支持 <!--解压rar压缩--><dependency><gro ...

  4. opencv实现从视频读取每一帧图像保存并合成avi格式视频

    我的方法是用两个mat生成的对象,frame,src,frame是读取了视频的每一帧图像,并实现了保存,src是单纯用于合成视频.目前有出现两个bug,一个是生成的avi格式视频过大,一个是获取的图像 ...

  5. 【嵌入式烧录/刷写文件】-1.1-详解Motorola S-record(S19/SREC/mot/SX)格式文件

    目录 1 什么是Motorola S-record 2 Motorola S-record的格式 2.1 Motorola S-record的结构 2.1.1 "Record type记录类 ...

  6. ffmpeg解封装及解码实战

    ffmpeg解封装及解码实战 目录 封装格式相关函数 解封装流程 补充 分离AAC和H264 1. 封装格式相关函数 1. 基本概念 2. 相关函数 1. avformat_alloc_context ...

  7. 【python实现视频解帧并保存到文件夹】

    [python实现视频解帧并保存文件夹] 1.功能说明 2.代码实现 3.函数方法解析 ① os.getcwd() ② cv2.VideoCapture().get方法获取视频的相关参数 ③ cv2. ...

  8. PDPS软件:PSZ格式文件的保存与打开方法

    目录 概述 PSZ格式文件保存方法 PSZ格式文件打开方法 本文已经首发在个人微信公众号:工业机器人仿真与编程(微信号:IndRobSim),欢迎关注! 概述 之前有很多小伙伴问过,PDPS软件保存的 ...

  9. 采用FFmpeg从视频中提取音频(声音)保存为mp3文件

    采用FFmpeg从视频中提取音频(声音)保存为mp3文件 作者:雨水,日期:2016年1月9日 CSDN博客:http://blog.csdn.net/gobitan 摘要:看到好的视频文件,如果想把 ...

最新文章

  1. 1、java集合:java集合详解及类关系图
  2. isNumeric isInteger isDate
  3. 【转载】JAVAEE之内置对象和属性范围
  4. Robotium双client測试框架
  5. spring源码分析2本最高清带书目PDF百度网盘分享
  6. 女性买房需要注意哪些问题
  7. 我学会了用计算机作文,我学会了做饭作文300字(通用10篇)
  8. gcd常见结论及gcd与斐波那契结合--hdu6363.
  9. 获取文件绝对路径最后的文件夹名称
  10. 函数和存储过程的区别
  11. 中点画线算法画直线----计算机图形学
  12. C语言知识点总结2022
  13. 时间差之天数计算python123
  14. ESP8266学习笔记(3)——GPIO接口使用
  15. android 表情包下载,表情包制作pro
  16. Python入门后,想要从事自由职业可以做哪方面工作?
  17. Java FX 表格数据赋值
  18. 我辞退了一名核心高管:不躬身入局,不配做管理者
  19. 蓝桥杯单片机led指示
  20. 河北省 河南省 安徽省 黑龙江省 辽宁省 吉林省 贵州省 陕西省 山东省 云南省 广西省二级建造师 一级建造师...

热门文章

  1. LINK : fatal error LNK1104: 无法打开文件“mfc140u.lib” 错误解决方案
  2. 使用JS实现当当购物车结算页面
  3. 生成模型和判别模型的对比,懂这俩机器学习不在话下 最大熵模型
  4. L1-040 最佳情侣身高差(10 分)
  5. echarts修改横轴/xAxis的样式
  6. Homebrew工具命令之brew cleanup清理电脑内存
  7. 智能家居开源生态—正确的HTTP API 接口规范以及设备类插件实现
  8. 数据安全三要素:机密性、完整性、身份验证
  9. java修图sdk_脑洞大开!Adobe等新研究把「自拍」变「他拍」,魔幻修图效果感人...
  10. 云服务案例分析 BB平台 Quiz6