本文基于 linux 环境,通过安信可 ESP32-Cam 开发板 SDK C语言编程二次开发,本地拍照图片上传到指定的服务器。
-
安信可 ESP32-Cam 开发板:https://item.taobao.com/item.htm?id=573698917181
-
TTL-USB 调试工具(推荐使用这个,保证足够的电压电流):https://item.taobao.com/item.htm?id=565546260974
- 环境搭建:Linux环境搭建 /relese/v3.3.2 分支
- esp-idf commitId:
b4c0751692a18db098a9a6139b2ab5a789d39167
- 工具链设置:下载 toolchain,博主使用的版本是:
gcc version 5.2.0 (crosstool-NG crosstool-ng-1.22.0-97-gc752ad5)
- Python版本:
Python 2.7.17
本代码以HTTP 协议POST提交 ,数据流形式把图片上传到服务器。其格式如下:
POST /index.php HTTP/1.1
Host: www.domain.com
Content-Type: image/jpeg
Content-Length: 12540
"<file contents here>"
因此,服务器要以数据流接收,以 PHP
语言为例:
//接受数据流
$stream = file_get_contents('php://input');
//数据流转化为png格式,并保存在指定的位置
$len = file_put_contents('/www/wwwroot/static/' . time() . ".png", $stream);
文件目录说明:
├─1_take_pic_http_to_cloud
│ ├─components 摄像头驱动代码组件
│ ├─main 用户程序
│ │ ├─app_wifi.c/h 连接路由器的逻辑实现
│ │ ├─main.c 主文件程序入口
主文件逻辑代码协议详解:
static void http_test_task(void *pvParameters)
{
//等待Wi-Fi连接成功
app_wifi_wait_connected();
ESP_LOGI(TAG, "Http Start");
size_t _jpg_buf_len;
uint8_t *_jpg_buf;
camera_fb_t *pic = NULL;
esp_err_t res = ESP_OK;
size_t fb_len = 0;
//配置服务器相关信息
esp_http_client_config_t config = {
.url = "http://www.domain.com/index.php",
.method = HTTP_METHOD_POST,
.event_handler = _http_event_handler,
.buffer_size = 4096,
.timeout_ms = 10000,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
//开始拍照
pic = esp_camera_fb_get();
if (!pic)
{
ESP_LOGE(TAG, "Camera capture failed");
}
else
{
//拍照成功,获取其大小、尺寸等信息
ESP_LOGI(TAG, "Camera capture OK , Its size was: %zu bytes", pic->len);
ESP_LOGI(TAG, "Camera capture OK , Its width was: %d", pic->width);
ESP_LOGI(TAG, "Camera capture OK , Its height was: %d ", pic->height);
//设置HTTP请求头为image/jpg表示图片类型
res = esp_http_client_set_header(client, "Content-Type", "image/jpg");
if (res != ESP_OK)
{
ESP_LOGE(TAG, "esp_http_client_set_header result code : [%s]", esp_err_to_name(res));
goto end;
}
//把图片放在body里面
res = esp_http_client_set_post_field(client, (const char *)pic->buf, pic->len);
if (res != ESP_OK)
{
ESP_LOGE(TAG, "esp_http_client_set_post_field result code : [%s]", esp_err_to_name(res));
goto end;
}
vTaskDelay(1000 / portTICK_RATE_MS);
//开始执行请求服务器
res = esp_http_client_perform(client);
//判断是否请求成功
if (res == ESP_OK)
{
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %d",
esp_http_client_get_status_code(client), esp_http_client_get_content_length(client));
}
else
{
ESP_LOGE(TAG, "perform http request %s", esp_err_to_name(res));
}
}
end:
{
esp_camera_fb_return(pic);
esp_http_client_cleanup(client);
free(buffer);
}
ESP_LOGI(TAG, "Http End");
vTaskDelete(NULL);
}