|
37 | 37 | #endif |
38 | 38 |
|
39 | 39 | // Supporting functions |
40 | | -void raise_micropython_error_from_esp_err(esp_err_t err) { |
| 40 | +static void raise_micropython_error_from_esp_err(esp_err_t err) { |
41 | 41 | switch (err) { |
42 | 42 | case ESP_OK: |
43 | 43 | return; |
@@ -80,7 +80,7 @@ static int map(int value, int fromLow, int fromHigh, int toLow, int toHigh) { |
80 | 80 | return (int)((int32_t)(value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow); |
81 | 81 | } |
82 | 82 |
|
83 | | -static int get_mapped_jpeg_quality(int8_t quality) { |
| 83 | +static inline int get_mapped_jpeg_quality(int8_t quality) { |
84 | 84 | return map(quality, 0, 100, 63, 0); |
85 | 85 | } |
86 | 86 |
|
@@ -241,60 +241,80 @@ void mp_camera_hal_reconfigure(mp_camera_obj_t *self, mp_camera_framesize_t fram |
241 | 241 | } |
242 | 242 | } |
243 | 243 |
|
244 | | -mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, mp_camera_pixformat_t out_format) { |
| 244 | +mp_obj_t mp_camera_hal_capture(mp_camera_obj_t *self, int8_t out_format) { |
245 | 245 | if (!self->initialized) { |
246 | 246 | mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to capture image: Camera not initialized")); |
247 | 247 | } |
248 | 248 | if (self->captured_buffer) { |
249 | 249 | esp_camera_fb_return(self->captured_buffer); |
250 | 250 | self->captured_buffer = NULL; |
251 | 251 | } |
| 252 | + |
| 253 | + static size_t out_len = 0; |
| 254 | + static uint8_t *out_buf = NULL; |
| 255 | + if (out_len>0 || out_buf) { |
| 256 | + free(out_buf); |
| 257 | + out_len = 0; |
| 258 | + out_buf = NULL; |
| 259 | + } |
| 260 | + |
252 | 261 | ESP_LOGI(TAG, "Capturing image"); |
253 | 262 | self->captured_buffer = esp_camera_fb_get(); |
254 | | - if (self->captured_buffer) { |
| 263 | + if (!self->captured_buffer) { |
| 264 | + ESP_LOGE(TAG, "Failed to capture image"); |
| 265 | + return mp_const_none; |
| 266 | + } |
| 267 | + |
| 268 | + if (out_format >= 0 && (mp_camera_pixformat_t)out_format != self->camera_config.pixel_format) { |
255 | 269 | switch (out_format) { |
256 | 270 | case PIXFORMAT_JPEG: |
257 | | - return mp_const_none; |
| 271 | + if (frame2jpg(self->captured_buffer, self->camera_config.jpeg_quality, &out_buf, &out_len)) { |
| 272 | + esp_camera_fb_return(self->captured_buffer); |
| 273 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 274 | + return result; |
| 275 | + } else { |
| 276 | + return mp_const_none; |
| 277 | + } |
258 | 278 |
|
259 | 279 | case PIXFORMAT_RGB888: |
260 | | - size_t out_len = self->captured_buffer->width * self->captured_buffer->height * 3; |
261 | | - uint8_t *out_buf = (uint8_t *)malloc(out_len); |
| 280 | + out_len = self->captured_buffer->width * self->captured_buffer->height * 3; |
| 281 | + out_buf = (uint8_t *)malloc(out_len); |
262 | 282 | if (!out_buf) { |
263 | 283 | ESP_LOGE(TAG, "out_buf malloc failed"); |
264 | 284 | return mp_const_none; |
265 | 285 | } |
266 | | - if (fmt2rgb888(self->captured_buffer->buf, self->captured_buffer->len, self->captured_buffer->format, out_buf)){ |
| 286 | + if (fmt2rgb888(self->captured_buffer->buf, self->captured_buffer->len, self->captured_buffer->format, out_buf)) { |
267 | 287 | esp_camera_fb_return(self->captured_buffer); |
268 | | - mp_obj_t result = mp_obj_new_bytes(out_buf, out_len); |
269 | | - free(out_buf); |
| 288 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
270 | 289 | return result; |
271 | 290 | } else { |
272 | | - free(out_buf); |
273 | 291 | return mp_const_none; |
274 | 292 | } |
275 | | - |
| 293 | + |
276 | 294 | default: |
277 | | - if (self->camera_config.pixel_format == PIXFORMAT_JPEG) { |
278 | | - ESP_LOGI(TAG, "Captured image in JPEG format"); |
279 | | - return mp_obj_new_memoryview('b', self->captured_buffer->len, self->captured_buffer->buf); |
| 295 | + ESP_LOGI(TAG, "Returning image as bitmap"); |
| 296 | + if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) { |
| 297 | + esp_camera_fb_return(self->captured_buffer); |
| 298 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 299 | + return result; |
280 | 300 | } else { |
281 | | - ESP_LOGI(TAG, "Returning image as bitmap"); |
282 | | - uint8_t *out = NULL; |
283 | | - size_t out_len = 0; |
284 | | - if (frame2bmp(self->captured_buffer, &out, &out_len)) { |
285 | | - esp_camera_fb_return(self->captured_buffer); |
286 | | - mp_obj_t result = mp_obj_new_bytes(out, out_len); |
287 | | - free(out); |
288 | | - return result; |
289 | | - } else { |
290 | | - return mp_const_none; |
291 | | - } |
| 301 | + return mp_const_none; |
292 | 302 | } |
293 | 303 | } |
| 304 | + } |
| 305 | + |
| 306 | + if (self->camera_config.pixel_format == PIXFORMAT_JPEG) { |
| 307 | + ESP_LOGI(TAG, "Captured image in JPEG format"); |
| 308 | + return mp_obj_new_memoryview('b', self->captured_buffer->len, self->captured_buffer->buf); |
294 | 309 | } else { |
295 | | - esp_camera_fb_return(self->captured_buffer); |
296 | | - self->captured_buffer = NULL; |
297 | | - return mp_const_none; |
| 310 | + ESP_LOGI(TAG, "Returning image as bitmap"); |
| 311 | + if (frame2bmp(self->captured_buffer, &out_buf, &out_len)) { |
| 312 | + esp_camera_fb_return(self->captured_buffer); |
| 313 | + mp_obj_t result = mp_obj_new_memoryview('b', out_len, out_buf); |
| 314 | + return result; |
| 315 | + } else { |
| 316 | + return mp_const_none; |
| 317 | + } |
298 | 318 | } |
299 | 319 | } |
300 | 320 |
|
@@ -447,6 +467,7 @@ void mp_camera_hal_set_frame_size(mp_camera_obj_t * self, framesize_t value) { |
447 | 467 | self->camera_config.frame_size = value; |
448 | 468 | } |
449 | 469 | } |
| 470 | + |
450 | 471 | int mp_camera_hal_get_quality(mp_camera_obj_t * self) { |
451 | 472 | if (!self->initialized) { |
452 | 473 | mp_raise_ValueError(MP_ERROR_TEXT("Camera not initialized")); |
|
0 commit comments