2016-06-29 4 views
1

Ich möchte ein Bild mit den ffmpeg Funktionen (wie av_picture_crop oder vf_crop), nicht Befehlszeile Dienstprogramm zuschneiden.Wie AvFrame mit FFmpeg Funktionen zu croppen

Gibt es jemanden, der weiß, wie es geht?

Haben Sie den Quellcode für diese Funktion?

Antwort

2

av_picture_crop() ist deprecated.

vf_crop nutzen zu können, verwenden Sie die buffer und buffersink Filter in libavfilter:

#include "libavfilter/avfilter.h" 

static AVFrame *crop_frame(const AVFrame *in, int left, int top, int right, int bottom) 
{ 
    AVFilterContext *buffersink_ctx; 
    AVFilterContext *buffersrc_ctx; 
    AVFilterGraph *filter_graph = avfilter_graph_alloc(); 
    AVFrame *f = av_frame_alloc(); 
    AVFilterInOut *inputs = NULL, *outputs = NULL; 
    char args[512]; 
    int ret; 
    snprintf(args, sizeof(args), 
      "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];" 
      "[in]crop=x=%d:y=%d:out_w=in_w-x-%d:out_h=in_h-y-%d[out];" 
      "[out]buffersink", 
      frame->width, frame->height, frame->format, 
      left, top, right, bottom); 

    ret = avfilter_graph_parse2(filter_graph, args, &inputs, &outputs); 
    if (ret < 0) return NULL; 
    assert(inputs == NULL && outputs == NULL); 
    ret = avfilter_graph_config(filter_graph, NULL); 
    if (ret < 0) return NULL; 

    buffersrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_0"); 
    buffersink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_2"); 
    assert(buffersrc_ctx != NULL); 
    assert(buffersink_ctx != NULL); 

    av_frame_ref(f, in); 
    ret = av_buffersrc_add_frame(buffersrc_ctx, f); 
    if (ret < 0) return NULL; 
    ret = av_buffersink_get_frame(buffersink_ctx, f); 
    if (ret < 0) return NULL; 

    avfilter_graph_free(&filter_graph); 

    return f; 
} 

nicht zurückgegeben (croppped) Rahmen Vergessen av_frame_free() mit UNREF. Die Daten des Eingabeframes bleiben unverändert. Wenn Sie sie nicht über diese Funktion hinaus benötigen, müssen Sie auch den Eingabeframe av_frame_free() eingeben.

Wenn Sie viele Bilder beschneiden möchten, versuchen Sie, das Filterdiagramm zwischen den Bildern zu behalten und es nur dann zurückzusetzen (oder neu zu erstellen), wenn sich die Bildgröße/das Bildformat ändert. Ich überlasse es dir, herauszufinden, wie das geht.

+0

Vielen Dank Ronald, ich habe es irgendwie mit av_picture_crop() gehandhabt, aber wie du schon sagtest, dass es eine veraltete Funktion ist, werde ich es mit deinem Quellcode mit der vf_crop Funktion versuchen – eruslu

Verwandte Themen