2012-02-20 80 views
3

我有一个原始图像缓冲区(内存中)从我想要转换为JPEG(用于缩小尺寸)的相机中捕获。问题在于,将这些图像保存为.pgm格式会导致我无法承受的巨大文件大小,这是由于保存这种大小的大文件时存在内存限制和延迟(我正在处理的应用程序中存在一个限制) 。使用LIBAVCODEC将原始图像缓冲区隐藏为JPEG

我想知道如何使用LIBAVCODEC将图像缓冲区压缩/格式化为.jpg格式?我的图像捕捉代码在C.

+0

是否有你需要使用的,而不是一个libav一个原因图像特定的,甚至JPEG特异性,图书馆吗? – blahdiblah 2012-02-29 02:05:43

回答

6

此代码与YUV原始图像一起使用。我有segfault试图编码一个RGB原始图像。但你可以使用swscale()将RGB转换为YUV

int main() 
{ 
    int ret; 
    AVFrame *frame; 
    AVPacket pkt; 

    av_register_all(); 

    AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG); 
    if (!codec) 
    { 
     printf("Codec not found\n"); 
     exit(1); 
    } 

    AVCodecContext* c = avcodec_alloc_context3(codec); 
    if (!c) 
    { 
     printf("Could not allocate video codec context\n"); 
     exit(1); 
    } 

    c->bit_rate = 400000; 
    c->width = 320; 
    c->height = 200; 
    c->time_base= (AVRational){1,25}; 
    c->pix_fmt = AV_PIX_FMT_YUVJ420P; 

    if (avcodec_open2(c, codec, NULL) < 0) 
    { 
     printf("Could not open codec\n"); 
     exit(1); 
    } 

    frame = avcodec_alloc_frame(); 
    if (!frame) 
    { 
     printf("Could not allocate video frame\n"); 
     exit(1); 
    } 
    frame->format = c->pix_fmt; 
    frame->width = c->width; 
    frame->height = c->height; 

    ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, c->pix_fmt, 32); 
    if (ret < 0) 
    { 
     printf("Could not allocate raw picture buffer\n"); 
     exit(1); 
    } 

    av_init_packet(&pkt); 
    pkt.data = NULL; 
    pkt.size = 0; 

    /* prepare a dummy image */ 
    /* Y */ 
    for(int y=0;y<c->height;y++) { 
     for(int x=0;x<c->width;x++) { 
      frame->data[0][y * frame->linesize[0] + x] = x + y; 
     } 
    } 

    /* Cb and Cr */ 
    for(int y=0;y<c->height/2;y++) { 
     for(int x=0;x<c->width/2;x++) { 
      frame->data[1][y * frame->linesize[1] + x] = 128 + y; 
      frame->data[2][y * frame->linesize[2] + x] = 64 + x; 
     } 
    } 


    frame->pts = 1; 

    int got_output = 0; 
    ret = avcodec_encode_video2(c, &pkt, frame, &got_output); 
    if (ret < 0) 
    { 
     printf("Error encoding frame\n"); 
     exit(1); 
    } 

    if (got_output) 
    { 
     printf("got frame\n"); 
     FILE* f = fopen("x.jpg", "wb"); 
     fwrite(pkt.data, 1, pkt.size, f); 
     av_free_packet(&pkt); 
    } 

    avcodec_close(c); 
    av_free(c); 
    av_freep(&frame->data[0]); 
    avcodec_free_frame(&frame); 
    printf("\n"); 

    return 0; 
} 
相关问题