esp32如何将esp_camera_fb_get()得到的图片存进SD卡为JPG格式 写一个例程
时间: 2023-12-02 20:02:32 浏览: 280
下面是一个ESP32将摄像头拍摄的图片存储到SD卡中的示例程序,它将图片转换为JPG格式并保存到SD卡中:
```
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "driver/gpio.h"
#include "esp_vfs_fat.h"
#include "esp_log.h"
#define PIN_NUM_MISO 19
#define PIN_NUM_MOSI 23
#define PIN_NUM_CLK 18
#define PIN_NUM_CS 4
static const char* TAG = "example";
// 初始化 SD 卡
static void sd_card_init()
{
ESP_LOGI(TAG, "Initializing SD card");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
slot_config.gpio_miso = PIN_NUM_MISO;
slot_config.gpio_mosi = PIN_NUM_MOSI;
slot_config.gpio_sck = PIN_NUM_CLK;
slot_config.gpio_cs = PIN_NUM_CS;
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = true,
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
sdmmc_card_t* card;
esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. If you want the card to be formatted, set format_if_mount_failed = true.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
return;
}
sdmmc_card_print_info(stdout, card);
}
// 将图片转换为 JPG 格式并保存到 SD 卡中
void save_jpeg_to_sdcard(camera_fb_t * fb)
{
char *filename = "/sdcard/picture.jpg";
// 以二进制写方式打开文件
FILE *file = fopen(filename, "wb");
if (file == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
esp_jpeg_encoder_t *encoder = malloc(sizeof(esp_jpeg_encoder_t));
if (!encoder) {
ESP_LOGE(TAG, "JPEG encoder init error");
fclose(file);
return;
}
ESP_LOGI(TAG, "Encoding JPEG image");
// 初始化 JPEG 编码器
esp_err_t err = esp_jpeg_encoder_init(encoder);
if (err != ESP_OK) {
ESP_LOGE(TAG, "JPEG encoder init error");
fclose(file);
free(encoder);
return;
}
// 将图片转换为 RGB888 格式
uint8_t *rgb_buf = malloc(fb->width * fb->height * 3);
if (!rgb_buf) {
ESP_LOGE(TAG, "RGB buffer allocation failed");
fclose(file);
free(encoder);
esp_jpeg_encoder_deinit(encoder);
return;
}
size_t out_len;
err = fmt2rgb888(fb->buf, fb->len, fb->format, rgb_buf);
if (err != ESP_OK) {
ESP_LOGE(TAG, "RGB conversion error");
fclose(file);
free(encoder);
esp_jpeg_encoder_deinit(encoder);
free(rgb_buf);
return;
}
// 将 RGB888 格式的图片编码为 JPEG 格式
err = esp_jpeg_encode(encoder, rgb_buf, fb->width, fb->height, PIXFORMAT_RGB888, 95, file, &out_len);
if (err != ESP_OK) {
ESP_LOGE(TAG, "JPEG encoding error");
fclose(file);
free(encoder);
esp_jpeg_encoder_deinit(encoder);
free(rgb_buf);
return;
}
ESP_LOGI(TAG, "JPEG image saved to SD card");
fclose(file);
free(encoder);
esp_jpeg_encoder_deinit(encoder);
free(rgb_buf);
}
void app_main()
{
// 初始化摄像头
camera_config_t config = {
.pin_pwdn = -1,
.pin_reset = -1,
.pin_xclk = 32,
.pin_sscb_sda = 26,
.pin_sscb_scl = 27,
.pin_d7 = 35,
.pin_d6 = 34,
.pin_d5 = 39,
.pin_d4 = 36,
.pin_d3 = 21,
.pin_d2 = 19,
.pin_d1 = 18,
.pin_d0 = 5,
.pin_vsync = 25,
.pin_href = 23,
.pin_pclk = 22,
.xclk_freq_hz = 10000000,
.ledc_timer = LEDC_TIMER_0,
.ledc_channel = LEDC_CHANNEL_0,
.pixel_format = PIXFORMAT_JPEG,
.frame_size = FRAMESIZE_SVGA,
.jpeg_quality = 12,
.fb_count = 2
};
esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Camera init failed with error 0x%x", err);
return;
}
// 初始化 SD 卡
sd_card_init();
// 拍摄图片
camera_fb_t * fb = esp_camera_fb_get();
if (!fb) {
ESP_LOGE(TAG, "Camera capture failed");
return;
}
// 将图片保存到 SD 卡中
save_jpeg_to_sdcard(fb);
// 释放摄像头缓冲区
esp_camera_fb_return(fb);
ESP_LOGI(TAG, "Done");
}
```
这个示例代码需要使用开发板上的 SD 卡槽和一个 SD 卡。在这个示例中,我们首先初始化 SD 卡,然后拍摄一张图片,将其转换为 RGB888 格式,然后编码为 JPEG 格式并保存到 SD 卡中。
阅读全文