博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ffmpeg 对图像数据格式以及图片缩放
阅读量:2345 次
发布时间:2019-05-10

本文共 4507 字,大约阅读时间需要 15 分钟。

利用ffmpeg进行图像数据格式的转换以及图片的缩放应用中,主要用到了swscale.h文件中的三个函数,分别是:

struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,                               int dstW, int dstH, enum AVPixelFormat dstFormat,                               int flags, SwsFilter *srcFilter,                               SwsFilter *dstFilter, const double *param);
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],     const int srcStride[], int srcSliceY, int srcSliceH,                   uint8_t *const dst[], const int dstStride[]);
void sws_freeContext(struct SwsContext *swsContext);

sws_getContext函数可以看做是初始化函数,它的参数定义分别为:

int srcW,int srcH 为原始图像数据的高和宽;  int dstW,int dstH 为输出图像数据的高和宽;  enum AVPixelFormat srcFormat 为输入和输出图片数据的类型;eg:AV_PIX_FMT_YUV420、PAV_PIX_FMT_RGB24;  int flags 为scale算法种类;eg:SWS_FAST_BILINEAR,SWS_BICUBIC、SWS_BICUBLIN、SWS_POINT、SWS_SINC;  SwsFilter *srcFilter ,SwsFilter *dstFilter,const double *param 可以不用管,全为NULL即可;

sws_scale函数则为执行函数,它的参数定义分别为:

struct SwsContext *c 为sws_getContext函数返回的值;  const uint8_t *const srcSlice[],uint8_t *const dst[] 为输入输出图像数据各颜色通道的buffer指针数组;  const int srcStride[],const int dstStride[] 为输入输出图像数据各颜色通道每行存储的字节数数组;       int srcSliceY 为从输入图像数据的第多少列开始逐行扫描,通常设为0;  int srcSliceH 为需要扫描多少行,通常为输入图像数据的高度;

sws_freeContext函数为结束函数,它的参数即为sws_getContext函数返回的值;

做一个实际缩放YUV420函数打包实例如下:

int ScaleImg(AVCodecContext *pCodecCtx,AVFrame *src_picture,AVFrame *dst_picture,int nDstH ,int nDstW ){int i ;int nSrcStride[3];int nDstStride[3];int nSrcH = pCodecCtx->height;int nSrcW = pCodecCtx->width;struct SwsContext* m_pSwsContext;uint8_t *pSrcBuff[3] = {src_picture->data[0],src_picture->data[1], src_picture->data[2]};nSrcStride[0] = nSrcW ;nSrcStride[1] = nSrcW/2 ;nSrcStride[2] = nSrcW/2 ;dst_picture->linesize[0] = nDstW;dst_picture->linesize[1] = nDstW / 2;dst_picture->linesize[2] = nDstW / 2;printf("nSrcW%d\n",nSrcW);m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P,nDstW, nDstH, PIX_FMT_YUV420P,SWS_BICUBIC,NULL, NULL, NULL);if (NULL == m_pSwsContext){printf("ffmpeg get context error!\n");exit (-1);}sws_scale(m_pSwsContext, src_picture->data,src_picture->linesize, 0, pCodecCtx->height,dst_picture->data,dst_picture->linesize);printf("line0:%d line1:%d line2:%d\n",dst_picture->linesize[0] ,dst_picture->linesize[1] ,dst_picture->linesize[2]);sws_freeContext(m_pSwsContext);return 1 ;}

函数很简单,申请环境初始指针,后缩放即可。读到此文的朋友,这个函数可以直接拷贝使用哟。

RGB的缩放可以参考下面:

int ScaleYUVImgToRGB(int nSrcW,int nSrcH ,uint8_t* src_data,int *linesize,int nDstW ,int nDstH )  {      int i ; int ret ;  FILE *nRGB_file ;    AVFrame *nDst_picture ;    struct SwsContext* m_pSwsContext;      nDst_picture = avcodec_alloc_frame();    if (!nDst_picture){        printf("nDst_picture avcodec_alloc_frame failed\n");        exit(1);    }    if(avpicture_alloc((AVPicture *)nDst_picture,PIX_FMT_RGB24,nDstW, nDstH)<0){        printf("dst_picture avpicture_alloc failed\n");        exit(1);    }    m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P,          nDstW, nDstH, PIX_FMT_RGB24,          SWS_BICUBIC,          NULL, NULL, NULL);      if (NULL == m_pSwsContext)      {          printf("ffmpeg get context error!\n");          exit (-1);      }       ret = sws_scale(m_pSwsContext, src_data,linesize, 0,nSrcH,nDst_picture->data,nDst_picture->linesize);      nRGB_file = fopen("..\\YUV_STREAM\\RGBFile.rgb","ab+");    fwrite(nDst_picture->data[0],nDstW*nDstH*3,1,nRGB_file);    fclose(nRGB_file);    sws_freeContext(m_pSwsContext);      avpicture_free((AVPicture *)nDst_picture);    return 0;  }

参数data 和 linesize 参考yuv平面指针即可。

同时如果不想使用AVPicture结构的话,可以参考下面的:(注意不同图像类型,linesize一定要写对)

char* H264Decoder_c::ScaleYUVImgToRGB(int nSrcW,int nSrcH ,uint8_t** src_data,int *linesize,int nDstW ,int nDstH ){    int i ; int ret ;  FILE *nRGB_file ;    struct SwsContext* m_pSwsContext;    char*  out_Img[3];    int out_linesize[3];    out_linesize[0] = 2*nDstW ; //out_linesize[1] = nDstW ;out_linesize[2] = nDstW ;    out_Img[0] = g_RGBImg ;    m_pSwsContext = sws_getContext(nSrcW, nSrcH, PIX_FMT_YUV420P,        nDstW, nDstH, PIX_FMT_RGB565,        SWS_BICUBIC,        NULL, NULL, NULL);    if (NULL == m_pSwsContext)    {        printf("ffmpeg get context error!\n");        exit (-1);    }    ret = sws_scale(m_pSwsContext, src_data,linesize, 0,nSrcH,(uint8_t**)out_Img,out_linesize);#if 0    nRGB_file = fopen("./RGBFile.rgb","ab+");    fwrite(out_Img[0],nDstW*nDstH*2,1,nRGB_file);    fclose(nRGB_file);#endif    sws_freeContext(m_pSwsContext);    return out_Img[0];

转载地址:http://vqnvb.baihongyu.com/

你可能感兴趣的文章
拥有10年编程经验的你,为什么还一直停留在原地
查看>>
Flask vs Django,Python Web开发用哪个框架更好
查看>>
Python说:常见的数据分析库有哪些
查看>>
Python教程:Python数据类型之字典
查看>>
Python基础教程:python的数据类型
查看>>
Python学习教程:另辟蹊径,appium抓取app应用数据了解一下
查看>>
Python学习教程:用Python进行金融市场文本数据的情感计算
查看>>
Python爬虫:python获取各种街拍美图
查看>>
爬虫工程师是干什么的?你真的知道吗?
查看>>
写给那些想学Python的人,建议收藏后细看
查看>>
数据全裸时代,你的隐私有多容易获取?
查看>>
分析http代理报错问题
查看>>
Python编程学习笔记 - 列表的各种姿势
查看>>
Python学习教程:Python入门笔记整理
查看>>
天了噜,居然用Python查到了女神的姓名
查看>>
常用排序算法总结
查看>>
Java输入输出
查看>>
MSSQL数据库常见问题
查看>>
Java8 Lambda
查看>>
JAVA面试700问
查看>>