2012-02-20 3 views
3

나는 (크기를 줄이기 위해) JPEG로 변환하려는 카메라에서 캡처 한 원시 이미지 버퍼 (메모리에 있음)가 있습니다. 문제는 이러한 이미지를 .pgm 형식으로 저장하면이 크기의 거대한 파일 (작업중인 응용 프로그램의 제약 조건)을 저장하는 데 필요한 메모리 제한 및 대기 시간으로 인해 막대한 비용을 감당할 수없는 결과를 낳을 수 있다는 것입니다. .LIBAVCODEC을 사용하여 JPEG로 숨겨진 원시 이미지 버퍼

LIBAVCODEC을 사용하여 이미지 버퍼를 .jpg 형식으로 압축/인코딩하는 방법을 알고 싶습니다. 내 이미지 캡처 코드는 C입니다.

+0

YUV하는 RGB 변환 swscale()를 사용할 수 있습니까? – blahdiblah

답변

6

이 코드는 YUV 원시 이미지와 함께 작동합니다. RGB 이미지를 인코딩하려고하는 segfault가 있습니다. 하지만 당신은 당신이 대신의 libav 사용해야하는 이유 이미지 별, 또는 JPEG 별, 도서관 있습니까

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; 
}