欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > C语言通过libjpeg-turbo将NV12转为jpeg

C语言通过libjpeg-turbo将NV12转为jpeg

2025/12/4 16:52:43 来源:https://blog.csdn.net/qqq1112345/article/details/143888015  浏览:    关键词:C语言通过libjpeg-turbo将NV12转为jpeg

C语言通过libjpeg-turbo将NV12转为jpeg

文章目录

  • C语言通过libjpeg-turbo将NV12转为jpeg
  • 前言
  • 直接贴源码
  • 参考

前言

OpenHarmony5.0.0的环境中需要将底层生成的NV12格式照片转化为jpeg并保存。
搜了一下相关的文章,发现没有合适的源码可以拿来用,于是尝试了“文心一言”竟然是可以的。稍作调试即可使用。

直接贴源码

main.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "camera_operate.h"int main(int argc, char* argv[])
{char id[8];memset(id, 0, sizeof(id));strcpy(id, "0");char path[128];memset(path, 0, sizeof(path));int ret = 0;ret = initCamera(id);if(0 != ret){printf("initCamera failed\n");}ret = takePicture(path); if(0 != ret){printf("takePicture failed\n");}ret = releaseCamera(id);if(0 != ret){printf("releaseCamera failed\n");}return 0;
}

camera_operate.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// /dev/cam_sensor0  /dev/cam_sensor2
/* input:"0":  /system/profile/k1-x_MUSE-Paper_sensor0_gc08a8.json  k1 camera in front"1":  /system/profile/k1-x_MUSE-Paper_sensor2_gc13a0.json  k1 camera in back"2":  /system/profile/k1-x_MUSE-Paper-mini-4g_sensor0_gc2375h.json  mini camera in front"3":  /system/profile/k1-x_MUSE-Paper-mini-4g_sensor2_gc5035.json   mini camera in back*/
int initCamera(char* id);/*output: photo path*/
int takePicture(char* photoPath); /* input: same as initCamera*/
int releaseCamera(char* id);

camera_operate.c
以下部分extern和变量是没有用到的。主要接口为nv12_to_rgb()

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <turbojpeg.h>
#include <jpeglib.h>#include "camera_operate.h"// 宏定义用于裁剪值的函数
#define CLAMP(x, low, high) ((x) > (high) ? (high) : ((x) < (low) ? (low) : (x)))#define MAX_BUFFER_RAWDUMP_NUM 5
#define MAX_BUFFER_NUM   4
#define MAX_PIPELINE_NUM 2
#define MAX_FIRMWARE_NUM 2
#define RAW8_DUMP_SIZE(w, h) ((w / 16 + (w % 16 ? 1 : 0)) * 16 * h)
#define RAW10_DUMP_SIZE(w, h) ((w / 12 + (w % 12 ? 1 : 0)) * 16 * h)
#define RAW12_DUMP_SIZE(w, h) ((w / 10 + (w % 10 ? 1 : 0)) * 16 * h)
#define RAW14_DUMP_SIZE(w, h) ((w / 8 + (w % 8 ? 1 : 0)) * 16 * h)
#define VRF_INFO_LEN (128)
#define AUTO_FRAME_NUM (500)
#define DUMP_FRAME_NUM (AUTO_FRAME_NUM / 2)
#define JPEG_QUALITY 75extern THREAD_INFO pipelineProcThread[MAX_PIPELINE_NUM];
extern int streamOnFlags[MAX_PIPELINE_NUM];
extern int outputDumpFlag[MAX_PIPELINE_NUM];
extern int showFps;
extern int dumpFrame;
extern int testFrame;
extern int testAutoRunFlag[MAX_PIPELINE_NUM];
extern struct condition testAutoRunCond[MAX_PIPELINE_NUM];IMAGE_INFO_S img_info                = {0};
struct testConfig config             = {0};
SENSOR_MODULE_INFO sensor_info       = {0};
void* sensorHandle                   = NULL;
int pipelineId   = 0;
int firmwareId   = 0;struct Rawimage_t 
{size_t input_w, input_h;unsigned char *yuv420sp;
}tRawImage;int initCamera(char* id)
{return 0;
}void nv12_to_rgb(const uint8_t *nv12, uint8_t *rgb, int width, int height)
{int y_size              = width * height;const uint8_t *y_plane  = nv12;const uint8_t *uv_plane = nv12 + y_size;for (int j = 0; j < height; j++){for (int i = 0; i < width; i++) {int y = y_plane[j * width + i];int u, v;int uv_index = ((j / 2) * (width / 2)) + (i / 2);if ((j % 2 == 0) && (i % 2 == 0)) {u = uv_plane[uv_index * 2];v = uv_plane[uv_index * 2 + 1];} else {// 简单的双线性插值int u1 = uv_plane[((uv_index - (width / 2 * (j % 2))) & (width / 2 - 1)) * 2];int v1 = uv_plane[((uv_index - (width / 2 * (j % 2))) & (width / 2 - 1)) * 2 + 1];int u2 = uv_plane[((uv_index + (width / 2 * (1 - j % 2))) & (width / 2 - 1)) * 2];int v2 = uv_plane[((uv_index + (width / 2 * (1 - j % 2))) & (width / 2 - 1)) * 2 + 1];u = (u1 + u2) >> 1;v = (v1 + v2) >> 1;}// YUV到RGB的转换(BT.601标准,适用于SDTV)int r = y + (1.402 * (v - 128));int g = y - (0.344136 * (u - 128)) - (0.714136 * (v - 128));int b = y + (1.772 * (u - 128));// 裁剪到0-255范围并转换为无符号8位整数rgb[(j * width + i) * 3]     = CLAMP(r, 0, 255);rgb[(j * width + i) * 3 + 1] = CLAMP(g, 0, 255);rgb[(j * width + i) * 3 + 2] = CLAMP(b, 0, 255);}}
}static void GetCurrentTime(char *Timebuf, int len)
{time_t CurTime;struct tm *pLocalTime = NULL;CurTime = time(NULL);pLocalTime = localtime(&CurTime);snprintf(Timebuf, len-1, "%04d%02d%02d-%02d:%02d:%02d",1900 + pLocalTime->tm_year, (1 + pLocalTime->tm_mon)%100, pLocalTime->tm_mday%100, pLocalTime->tm_hour%100, pLocalTime->tm_min%100, pLocalTime->tm_sec%100);
}int takePicture(char* path)
{//yuv to jpegprintf("-----start nv12 2 jpeg-----\n");//caculateN V12data sizesize_t nv12_size = img_info.width * img_info.height * 3 / 2;uint8_t *nv12    = (uint8_t *)malloc(nv12_size);uint8_t *rgb     = (uint8_t *)malloc(img_info.width * img_info.height * 3);if (!nv12 || !rgb){printf( "Memory allocation failed\n");free(nv12);free(rgb);return -1;}// read data from NV12fileFILE *infile = fopen(nv12filename, "rb");if (!infile){printf("Failed to open input file %s\n", nv12filename);free(nv12);free(rgb);return -2;}fread(nv12, 1, nv12_size, infile);fclose(infile);// NV12 to RGBnv12_to_rgb(nv12, rgb, img_info.width, img_info.height);// set JPEG depress parastruct jpeg_compress_struct cinfo;struct jpeg_error_mgr jerr;cinfo.err = jpeg_std_error(&jerr);jpeg_create_compress(&cinfo);FILE *outfile = fopen(jpegfilename, "wb");if (!outfile){printf("can't open %s\n", jpegfilename);jpeg_destroy_compress(&cinfo);free(nv12);free(rgb);return -1;}jpeg_stdio_dest(&cinfo, outfile);cinfo.image_width      = img_info.width;cinfo.image_height     = img_info.height;cinfo.input_components = 3;cinfo.in_color_space   = JCS_RGB;jpeg_set_defaults(&cinfo);jpeg_set_quality(&cinfo, 90, TRUE); // set JPEG quality level(0-100)jpeg_start_compress(&cinfo, TRUE);JSAMPROW row_pointer[1];int row_stride = img_info.width * 3;// 写入扫描行到JPEG文件while (cinfo.next_scanline < cinfo.image_height) {row_pointer[0] = &rgb[cinfo.next_scanline * row_stride];jpeg_write_scanlines(&cinfo, row_pointer, 1);}jpeg_finish_compress(&cinfo);fclose(outfile);jpeg_destroy_compress(&cinfo);// 释放内存free(nv12);free(rgb);printf("-----nv12 2 jpeg fin-----\n");return 0;
}
int releaseCamera(char* id)
{return 0;
}

参考

https://yiyan.baidu.com/chat/4595622732
https://blog.csdn.net/quantum7/article/details/82659539
https://zhuanlan.zhihu.com/p/698293711

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词