以下是一个实现将两张NV12格式的图片左右拼接的C语言代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define WIDTH 640
#define HEIGHT 480

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, 'Usage: %s file1.nv12 file2.nv12\n', argv[0]);
        return 1;
    }

    // 打开文件1
    FILE *f1 = fopen(argv[1], 'rb');
    if (!f1) {
        perror('Failed to open file1');
        return 1;
    }

    // 打开文件2
    FILE *f2 = fopen(argv[2], 'rb');
    if (!f2) {
        perror('Failed to open file2');
        return 1;
    }

    // 读取文件1的数据
    uint8_t *data1 = (uint8_t *)malloc(WIDTH * HEIGHT * 3 / 2);
    if (!data1) {
        perror('Failed to allocate memory for file1');
        return 1;
    }
    size_t n1 = fread(data1, 1, WIDTH * HEIGHT * 3 / 2, f1);
    if (n1 != WIDTH * HEIGHT * 3 / 2) {
        fprintf(stderr, 'Failed to read data from file1\n');
        return 1;
    }

    // 读取文件2的数据
    uint8_t *data2 = (uint8_t *)malloc(WIDTH * HEIGHT * 3 / 2);
    if (!data2) {
        perror('Failed to allocate memory for file2');
        return 1;
    }
    size_t n2 = fread(data2, 1, WIDTH * HEIGHT * 3 / 2, f2);
    if (n2 != WIDTH * HEIGHT * 3 / 2) {
        fprintf(stderr, 'Failed to read data from file2\n');
        return 1;
    }

    // 创建输出文件
    FILE *fout = fopen('output.nv12', 'wb');
    if (!fout) {
        perror('Failed to create output file');
        return 1;
    }

    // 将两张图片左右拼接
    uint8_t *out = (uint8_t *)malloc(WIDTH * HEIGHT * 3);
    if (!out) {
        perror('Failed to allocate memory for output');
        return 1;
    }
    for (int i = 0; i < HEIGHT; i++) {
        // 拼接Y分量
        memcpy(out + i * WIDTH * 2, data1 + i * WIDTH, WIDTH);
        memcpy(out + i * WIDTH * 2 + WIDTH, data2 + i * WIDTH, WIDTH);

        // 拼接UV分量
        for (int j = 0; j < WIDTH / 2; j++) {
            out[WIDTH * HEIGHT + i * WIDTH + j * 2] = data1[WIDTH * HEIGHT + i / 2 * WIDTH + j];
            out[WIDTH * HEIGHT + i * WIDTH + j * 2 + 1] = data1[WIDTH * HEIGHT + i / 2 * WIDTH + j + WIDTH / 2];
            out[WIDTH * HEIGHT * 3 / 2 + i * WIDTH + j * 2] = data2[WIDTH * HEIGHT + i / 2 * WIDTH + j];
            out[WIDTH * HEIGHT * 3 / 2 + i * WIDTH + j * 2 + 1] = data2[WIDTH * HEIGHT + i / 2 * WIDTH + j + WIDTH / 2];
        }
    }

    // 将拼接后的图片写入输出文件
    size_t n3 = fwrite(out, 1, WIDTH * HEIGHT * 3, fout);
    if (n3 != WIDTH * HEIGHT * 3) {
        fprintf(stderr, 'Failed to write data to output file\n');
        return 1;
    }

    // 释放内存和关闭文件
    free(data1);
    free(data2);
    free(out);
    fclose(f1);
    fclose(f2);
    fclose(fout);

    return 0;
}

该代码将两张NV12格式的图片左右拼接,并将结果写入名为output.nv12的文件中。可以通过修改代码将其改为上下拼接。需要注意的是,该代码仅适用于相同宽度和高度的图片。如果要拼接不同大小的图片,需要进行额外的处理。

实现上下拼接:

在代码中,将Y分量和UV分量的拼接方式调整如下:

// 拼接Y分量
memcpy(out + i * WIDTH * 2, data1 + i * WIDTH, WIDTH);
memcpy(out + (i + HEIGHT) * WIDTH * 2, data2 + i * WIDTH, WIDTH);

// 拼接UV分量
for (int j = 0; j < WIDTH / 2; j++) {
    out[WIDTH * HEIGHT + i * WIDTH + j * 2] = data1[WIDTH * HEIGHT + i / 2 * WIDTH + j];
    out[WIDTH * HEIGHT + i * WIDTH + j * 2 + 1] = data1[WIDTH * HEIGHT + i / 2 * WIDTH + j + WIDTH / 2];
    out[WIDTH * HEIGHT * 3 / 2 + (i + HEIGHT / 2) * WIDTH + j * 2] = data2[WIDTH * HEIGHT + i / 2 * WIDTH + j];
    out[WIDTH * HEIGHT * 3 / 2 + (i + HEIGHT / 2) * WIDTH + j * 2 + 1] = data2[WIDTH * HEIGHT + i / 2 * WIDTH + j + WIDTH / 2];
}

代码说明:

  1. 文件读取: 代码首先打开两个NV12格式的输入文件,并分别读取文件内容到data1和data2数组中。
  2. 内存分配: 为输出文件创建一个数组out,其大小为两张图片的总大小。
  3. 拼接操作: 代码分别对Y分量和UV分量进行拼接,并将拼接后的数据写入out数组。
  4. 写入输出文件: 代码将out数组中的数据写入output.nv12文件。
  5. 内存释放和文件关闭: 代码最后释放分配的内存,并关闭所有打开的文件。

注意事项:

  1. 该代码假设两张图片的宽度和高度相同。如果要拼接不同大小的图片,需要进行额外的处理。
  2. 代码中定义了WIDTH和HEIGHT宏,分别代表图片的宽度和高度。根据实际情况修改这些宏的值。
  3. 代码中使用memcpy函数来复制数据,可以根据实际情况选择更合适的复制方法。

应用场景:

该代码可应用于图像处理、视频编解码等领域,例如:

  • 将多张图片合并成一张大图。
  • 将视频帧拼接成连续的视频流。
  • 实现图像的分割和拼接等操作。

扩展阅读:

  • NV12格式:https://en.wikipedia.org/wiki/YUV#NV12
  • C语言内存管理:https://www.tutorialspoint.com/cprogramming/c_memory_management.htm
  • 图像处理库:https://www.opencv.org/
C语言实现NV12图片拼接:左右和上下拼接方法

原文地址: https://www.cveoy.top/t/topic/lGOb 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录