Tried to save the picture taken from ESP32Cam module, into SD Card as JPG file but it fail to open in Windows.
I have followed the code to take picture as is present at the below link: https://github.com/espressif/esp32-camera/blob/6a9497bbe909165663d958986e621e98dabcf994/examples/main/take_picture.c
After taking the picture I am converting it to jpg file using "frame2jpg". The camera used is OV2640. After conversion I am saving as.jpg file in SD Card. The SD card I moved to Windows PC and tried to open the saved .jpg file, but it does not open. It gives a message that file in not recognized.
Do I need to do more than just "frame2jpg" to convert it in right format?
[EDIT]: Moved "esp_camera_fb_return" after fclose.
void app_main()
{
mount_sdcard();
if(ESP_OK != init_camera()) {
return;
}
int suffix = 0;
char fnsuffix[25];
size_t cnv_buf_len;
uint8_t * cnv_buf = NULL;
while (suffix < 3) {
ESP_LOGI(TAG, "Taking picture...");
camera_fb_t *pic = esp_camera_fb_get();
// 20210922 convert to jpg -start
// bool isConverted = frame2bmp(pic, &cnv_buf, &cnv_buf_len);
bool isConverted = frame2jpg(pic, 80, &cnv_buf, &cnv_buf_len);
if(!isConverted){ ESP_LOGE(TAG,"failed to convert"); }
// 20210922 convert to jpg -end
// picture in a file-------------
suffix ;
char* cntStr= itoa(suffix,countFile,10);
// create a file.
ESP_LOGI(TAG, "Opening file");
strcpy(fnsuffix, MOUNT_POINT);
strcat(fnsuffix, "/fnb");
strcat(fnsuffix, cntStr);
// strcat(fnsuffix, ".bmp");
strcat(fnsuffix, ".jpg");
ESP_LOGI(TAG, "Opening file %s",fnsuffix);
FILE *f = fopen(fnsuffix, "wb");
if (f == NULL) {ESP_LOGE(TAG, "Failed to open file for writing"); return;}
fwrite(pic->buf, pic->len,1,f);
fclose(f);
ESP_LOGI(TAG, " picture file written as %s. size=%zu",fnsuffix,pic->len);
//save done-----------------------------
esp_camera_fb_return(pic);
vTaskDelay(5000 / portTICK_RATE_MS);
}
}
Added Hex Editor of JPG
43 4b 43 4b 43 68 43 68 4b 2b 4b 2b 52 ec 4a cb
52 cb 52 cb 52 ea 52 ea 4a eb 42 cb 42 eb 42 ec
4b 2c 4b 2c 42 ea 43 0a 4a ea 53 0b 4a ec 4a
..... first 3 lines above
.... last 2 lines
18 e4 18 e4 18 c5 18 c4 18 c4 18 c4 18 c3 18 c3
18 c3 18 c3 18 a3 18 a2 18 c3 18 a3 18 a4 18 a4
Console log
I (785) cpu_start: Application information:
I (787) cpu_start: Project name: camera_example
I (793) cpu_start: App version: 3022601-dirty
I (799) cpu_start: Compile time: Sep 19 2021 20:46:16
I (805) cpu_start: ELF file SHA256: b574883f4e49fb5a...
I (811) cpu_start: ESP-IDF: baseline-dirty
I (816) heap_init: Initializing. RAM available for dynamic allocation:
I (823) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (829) heap_init: At 3FFB6650 len 000299B0 (166 KiB): DRAM
I (836) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM
I (842) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (848) heap_init: At 40093438 len 0000CBC8 (50 KiB): IRAM
I (855) spiram: Adding pool of 4096K of external SPI memory to heap allocator
I (863) spi_flash: detected chip: generic
I (867) spi_flash: flash io: qio
I (872) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
I (887) spiram: Reserving pool of 32K of internal memory for DMA/internal allocations
I (895) example:take_picture: format_if_mount_failed is 0
I (901) example:take_picture: Initializing SD card
I (907) example:take_picture: Using SDMMC peripheral
I (913) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
Name: SU08G
Type: SDHC/SDXC
Speed: 20 MHz
Size: 7580MB
I (1081) gpio: GPIO[25]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:2
I (1084) cam_hal: cam init ok
I (1088) sccb: pin_sda 26 pin_scl 27
I (1092) gpio: GPIO[32]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (1131) camera: Detected camera at address=0x30
I (1134) camera: Detected OV2640 camera
I (1134) camera: Camera PID=0x26 VER=0x42 MIDL=0x7f MIDH=0xa2
I (1214) esp32 ll_cam: node_size: 2560, nodes_per_line: 1, lines_per_node: 1, dma_half_buffer_min: 2560, dma_half_buffer: 15360, lines_per_half_buffer: 6, dma_buffer_size: 30720, image_size: 153600
I (1222) cam_hal: buffer_size: 30720, half_buffer_size: 15360, node_buffer_size: 2560, node_cnt: 12, total_cnt: 10
I (1233) cam_hal: Allocating 153600 Byte frame buffer in PSRAM
I (1240) cam_hal: cam config ok
I (1243) ov2640: Set PLL: clk_2x: 0, clk_div: 3, pclk_auto: 1, pclk_div: 8
I (1321) example:take_picture: Taking picture...
I (1570) example:take_picture: Opening file
I (1570) example:take_picture: Opening file /sdcard/fnb1.jpg
I (2221) example:take_picture: picture file written as /sdcard/fnb1.jpg. size=153600
I (7221) example:take_picture: Taking picture...
I (7351) example:take_picture: Opening file
I (7351) example:take_picture: Opening file /sdcard/fnb2.jpg
I (7976) example:take_picture: picture file written as /sdcard/fnb2.jpg. size=153600
I (12976) example:take_picture: Taking picture...
I (13105) example:take_picture: Opening file
I (13105) example:take_picture: Opening file /sdcard/fnb3.jpg
I (13726) example:take_picture: picture file written as /sdcard/fnb3.jpg. size=153600
Edited Hex of JPG still did not open added ff d8 ff e0 to header also added trailer bytes as 8a 28 03 ff d9
The created file I am opening in photo (Windows). It gives message in Japanese which means "Sorry we donot support this file format or it is corrupted. We cannot open it in photo".
I also dragged and dropped in browser the JPG but it seems the bytes written to make jpg is not correct.
CodePudding user response:
Great, now the problem is much easier to debug. The data in the file is missing the JPEG header (ff d8 ff e0 00 10 4a 46 ...
) so it's probably the raw image data. If you look a the documentation for frame2jpg()
it shows that the buffer cnv_buf
will receive the JPEG image. That, however, is not what you're writing to the file. You're writing the original, unconverted frame with raw data:
fwrite(pic->buf, pic->len,1,f);
Instead you should write the output buffer from JPEG conversion. You also have to manually release that buffer later. E.g. (error handling omitted):
fwrite(cnv_buf, cnv_buf_len, 1, f);
fclose(f);
free(cnv_buf);
esp_camera_fb_return(pic);
See the HTTP stream example from the project's README for a more thorough example.