|
43 | 43 | #endif |
44 | 44 |
|
45 | 45 | // Supporting functions |
46 | | -void raise_micropython_error_from_esp_err(esp_err_t err) { |
| 46 | +static void raise_micropython_error_from_esp_err(esp_err_t err) { |
47 | 47 | switch (err) { |
48 | 48 | case ESP_OK: |
49 | 49 | return; |
@@ -86,7 +86,7 @@ static int map(int value, int fromLow, int fromHigh, int toLow, int toHigh) { |
86 | 86 | return (int)((int32_t)(value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow); |
87 | 87 | } |
88 | 88 |
|
89 | | -static int get_mapped_jpeg_quality(int8_t quality) { |
| 89 | +static inline int get_mapped_jpeg_quality(int8_t quality) { |
90 | 90 | return map(quality, 0, 100, 63, 0); |
91 | 91 | } |
92 | 92 |
|
@@ -247,60 +247,80 @@ void mp_camera_hal_reconfigure(mp_camera_obj_t *self, mp_camera_framesize_t fram |
247 | 247 | } |
248 | 248 | } |
249 | 249 |
|
250 | | -mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, mp_camera_pixformat_t out_format) { |
| 250 | +mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) { |
251 | 251 | if (!self->initialized) { |
252 | 252 | mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to capture image: Camera not initialized")); |
253 | 253 | } |
254 | 254 | if (self->captured_buffer) { |
255 | 255 | esp_camera_fb_return(self->captured_buffer); |
256 | 256 | self->captured_buffer = NULL; |
257 | 257 | } |
| 258 | + |
| 259 | + static size_t out_len = 0; |
| 260 | + static uint8_t *out_buf = NULL; |
| 261 | + if (out_len>0 || out_buf) { |
| 262 | + free(out_buf); |
| 263 | + out_len = 0; |
| 264 | + out_buf = NULL; |
| 265 | + } |
| 266 | + |
258 | 267 | ESP_LOGI(TAG, "Capturing image"); |
259 | 268 | self->captured_buffer = esp_camera_fb_get(); |
260 | | - if (self->captured_buffer) { |
| 269 | + if (!self->captured_buffer) { |
| 270 | + ESP_LOGE(TAG, "Failed to capture image"); |
| 271 | + return mp_const_none; |
| 272 | + } |
| 273 | + |
| 274 | + if (out_format >= 0 && (mp_camera_pixformat_t)out_format != self->camera_config.pixel_format) { |
261 | 275 | switch (out_format) { |
262 | 276 | case PIXFORMAT_JPEG: |
263 | | - return mp_const_none; |
| 277 | + if (frame2jpg(self->captured_buffer, self->camera_config.jpeg_quality, &out_buf, &out_len)) { |
| 278 | + esp_camera_fb_return(self->captured_buffer); |
| 279 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 280 | + return result; |
| 281 | + } else { |
| 282 | + return mp_const_none; |
| 283 | + } |
264 | 284 |
|
265 | 285 | case PIXFORMAT_RGB888: |
266 | | - size_t out_len = self->captured_buffer->width * self->captured_buffer->height * 3; |
267 | | - uint8_t *out_buf = (uint8_t *)malloc(out_len); |
| 286 | + out_len = self->captured_buffer->width * self->captured_buffer->height * 3; |
| 287 | + out_buf = (uint8_t *)malloc(out_len); |
268 | 288 | if (!out_buf) { |
269 | 289 | ESP_LOGE(TAG, "out_buf malloc failed"); |
270 | 290 | return mp_const_none; |
271 | 291 | } |
272 | | - if (fmt2rgb888(self->captured_buffer->buf, self->captured_buffer->len, self->captured_buffer->format, out_buf)){ |
| 292 | + if (fmt2rgb888(self->captured_buffer->buf, self->captured_buffer->len, self->captured_buffer->format, out_buf)) { |
273 | 293 | esp_camera_fb_return(self->captured_buffer); |
274 | | - mp_obj_t result = mp_obj_new_bytes(out_buf, out_len); |
275 | | - free(out_buf); |
| 294 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
276 | 295 | return result; |
277 | 296 | } else { |
278 | | - free(out_buf); |
279 | 297 | return mp_const_none; |
280 | 298 | } |
281 | | - |
| 299 | + |
282 | 300 | default: |
283 | | - if (self->camera_config.pixel_format == PIXFORMAT_JPEG) { |
284 | | - ESP_LOGI(TAG, "Captured image in JPEG format"); |
285 | | - return mp_obj_new_memoryview('b', self->captured_buffer->len, self->captured_buffer->buf); |
| 301 | + ESP_LOGI(TAG, "Returning image as bitmap"); |
| 302 | + if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) { |
| 303 | + esp_camera_fb_return(self->captured_buffer); |
| 304 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 305 | + return result; |
286 | 306 | } else { |
287 | | - ESP_LOGI(TAG, "Returning image as bitmap"); |
288 | | - uint8_t *out = NULL; |
289 | | - size_t out_len = 0; |
290 | | - if (frame2bmp(self->captured_buffer, &out, &out_len)) { |
291 | | - esp_camera_fb_return(self->captured_buffer); |
292 | | - mp_obj_t result = mp_obj_new_bytes(out, out_len); |
293 | | - free(out); |
294 | | - return result; |
295 | | - } else { |
296 | | - return mp_const_none; |
297 | | - } |
| 307 | + return mp_const_none; |
298 | 308 | } |
299 | 309 | } |
| 310 | + } |
| 311 | + |
| 312 | + if (self->camera_config.pixel_format == PIXFORMAT_JPEG) { |
| 313 | + ESP_LOGI(TAG, "Captured image in JPEG format"); |
| 314 | + return mp_obj_new_memoryview('b', self->captured_buffer->len, self->captured_buffer->buf); |
300 | 315 | } else { |
301 | | - esp_camera_fb_return(self->captured_buffer); |
302 | | - self->captured_buffer = NULL; |
303 | | - return mp_const_none; |
| 316 | + ESP_LOGI(TAG, "Returning image as bitmap"); |
| 317 | + if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) { |
| 318 | + esp_camera_fb_return(self->captured_buffer); |
| 319 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 320 | + return result; |
| 321 | + } else { |
| 322 | + return mp_const_none; |
| 323 | + } |
304 | 324 | } |
305 | 325 | } |
306 | 326 |
|
@@ -453,6 +473,7 @@ void mp_camera_hal_set_frame_size(mp_camera_obj_t * self, framesize_t value) { |
453 | 473 | self->camera_config.frame_size = value; |
454 | 474 | } |
455 | 475 | } |
| 476 | + |
456 | 477 | int mp_camera_hal_get_quality(mp_camera_obj_t * self) { |
457 | 478 | if (!self->initialized) { |
458 | 479 | mp_raise_ValueError(MP_ERROR_TEXT("Camera not initialized")); |
|
0 commit comments