首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >esp32 http_server html如何显示sd卡的图像

esp32 http_server html如何显示sd卡的图像
EN

Stack Overflow用户
提问于 2022-01-23 05:10:09
回答 1查看 748关注 0票数 0

我使用的是esp32cam模块和sdcard接口。我能够保存在sdcard中的图像。此图像在Windows中打开。接下来,我要添加http_server,并在html页面中访问sdcard中的图像,并在img标记的sdcard中使用。但是html不显示图像,在teraterm日志中它说它找不到文件。

代码语言:javascript
复制
 httpd_uri: httpd_uri: URI '/sdcard/fnb1.jpg' not found

为html请求提供服务的代码如下:

代码语言:javascript
复制
1   static esp_err_t hello_get_handler(httpd_req_t *req) {  
2   strcpy(ret_homepage,"<!DOCTYPE html><html><head><title>SwitchControl</title>"); 
3   strcat(ret_homepage, "</head><body>");  
4   strcat(ret_homepage, "<div>");  
5   strcat(ret_homepage, "Picture1:");  
6   strcat(ret_homepage,"<img src=\"/sdcard/fnb1.jpg\" width=\"500\" height=\"600\">"); 
7   strcat(ret_homepage, "</div>"); 
8       
9   strcat(ret_homepage, "</body>");    
10  strcat(ret_homepage, "</html>");    
11      
12  /* Set some custom headers */   
13  httpd_resp_set_hdr(req, "Connection", "close"); 
14  httpd_resp_set_hdr(req, "Cache-Control", "no-cache");   
15      
16  /* Send response with custom headers and body set as the    
17   * string passed in user context*/  
18  const char *resp_str = (const char*) ret_homepage;  
19      
20  httpd_resp_send(req, resp_str, HTTPD_RESP_USE_STRLEN);  
21      
22  ESP_LOGI(TAG, "Response sent for home page request.Time:%s",esp_log_system_timestamp());    
23      
24  return ESP_OK;  
25  }

在line#6这里

代码语言:javascript
复制
strcat(ret_homepage,"<img src=\"/sdcard/fnb1.jpg\" width=\"500\" height=\"600\">");

http_server似乎无法访问mount_point "/sdcard“,因此无法访问fbn1.jpg。

我所做的SD卡安装如下所示。此挂载工作良好,因为所编写的文件可从windows读取。下一件事是为什么上面的一行不读呢?它可能需要注册到虚拟文件系统(VFS)!如果是这样的话,那么在"esp_vfs_fat_sdspi_mount“之后,line#37需要做"esp_vfs_fat_register”才能工作吗?这里有谁能给我建议吗?

代码语言:javascript
复制
#define MOUNT_POINT "/sdcard"
....
1   void mount_sdcard(){    
2       esp_err_t ret;
3       esp_vfs_fat_sdmmc_mount_config_t mount_config = {
4       #ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
5               .format_if_mount_failed = true,
6       #else
7               .format_if_mount_failed = false,
8       #endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
9               .max_files = 5, .allocation_unit_size = 16 * 1024
10          };
11          sdmmc_card_t* card;
12          const char mount_point[] = MOUNT_POINT;
13          ESP_LOGI(TAG, "Initializing SD card");
14      #ifndef USE_SPI_MODE
15          ESP_LOGI(TAG, "Using SDMMC peripheral");
16          sdmmc_host_t host = SDMMC_HOST_DEFAULT();
17          sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
18      
19          // GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups.
20          gpio_set_pull_mode(15, GPIO_PULLUP_ONLY);   // CMD, needed in 4- and 1- line modes
21          //... omitted for brevity
22          gpio_set_pull_mode(13, GPIO_PULLUP_ONLY);   // D3, needed in 4- and 1-line modes
23          ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
24      #else
25          ESP_LOGI(TAG, "Using SPI peripheral");
26      
27          sdmmc_host_t host = SDSPI_HOST_DEFAULT();
28          spi_bus_config_t bus_cfg = {  .mosi_io_num = PIN_NUM_MOSI,.miso_io_num = PIN_NUM_MISO,.sclk_io_num = PIN_NUM_CLK,.quadwp_io_num = -1, .quadhd_io_num = -1, .max_transfer_sz = 4000,  };
29          ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN);
30          if (ret != ESP_OK) { ESP_LOGE(TAG, "Failed to initialize bus.");return;   }
31      
32          // This initializes the slot without card detect (CD) and write protect (WP) signals.
33          // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
34          sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
35          slot_config.gpio_cs = PIN_NUM_CS;slot_config.host_id = host.slot;
36      
37          ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
38      #endif //USE_SPI_MODE
39      
40          if (ret != ESP_OK) {   //...
41              return;
42          }
43      
44          // Card has been initialized, print its properties
45          sdmmc_card_print_info(stdout, card);
46  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-23 20:22:47

在做任何事情之前,你需要了解你在做什么。

您正在使用ESP32。你查过它的文档了吗?它甚至有一个示例程序。

现在,您已经为某些URI注册了一个处理程序。它看起来可能是这样的?:) (或者您更改了uri)。

代码语言:javascript
复制
static const httpd_uri_t hello = {
    .uri       = "/hello",
    .method    = HTTP_GET,
    .handler   = hello_get_handler,
    /* Let's pass response string in user
     * context to demonstrate it's usage */
    .user_ctx  = NULL 
};

...

httpd_register_uri_handler(server, &hello);

这意味着,如果服务器收到HTTP获取请求 for /hello,则程序调用hello_get_handler(),后者将使用您在处理程序中编写的HTML进行响应。

HTML文档都在那里。浏览器只接收您发送的文本,仅此而已。请参阅浏览器中的源代码。换句话说,在这个时候(或者永远),src=\"/sdcard/fnb1.jpg\"不会被图像所取代。

<img>标记/元素仅仅是浏览器用给定参数显示'src‘指向的资源的指令。“src”甚至可以是另一台服务器上的资源,例如:

代码语言:javascript
复制
<img src=\"http://cdn.sstatic.net/Img/teams/teams-illo-free-sidebar-promo.svg\">

(尝试使用图像的已知地址。)例外情况:图像也可以是整个图像文件的Base64编码字符串。但是,它不能是实际文件本身,即jpeg作为二进制blob。如果您真的想将图像嵌入到文档中,可以使用Base64方法,但这不是您在这里所要做的。

所以要重申的是,图像本身并不是在这里传输的。只有描述图像元素的HTML代码。纯文字。

浏览器将为图像资源本身发出单独的HTTP请求。您已经定义了一个相对URI,因此浏览器尝试从<your_server>/sdcard/fnb1.jpg获取它。

您的代码没有能够响应GET的处理程序,因此不会显示图像。

因此,让我们再一次假设您的ESP32获得IP 192.168.1.42,这基本上就是所发生的事情:

因此,您需要做的是实现和注册另一个句柄,它也可以为映像服务。此时,它可以是专门处理一个映像的处理程序。只需编写一些URI并将其嵌入到<img>中即可。当然,URI可以保持为/sdcard/fnb1.jpg --这并不重要。只需了解这是HTTP服务器中的URI。它与SD卡中图像的文件系统路径一点关系都没有。

响应HTTP 200 OK响应,至少使用标题‘content: image/jpeg’。根据文档 of httpd_resp_send

..。如果没有设置状态代码和内容类型,默认情况下这将发送200个OK状态代码和内容类型作为text/html。..。httpd_resp_set_type() -用于设置内容类型.

因此,只有内容类型需要由您设置("image/jpeg")。

再次:您需要定义一个响应处理程序,它可以处理对图像的GET请求。至少它可以是一个特定图像的硬编码URI。在处理程序中,需要使用httpd_resp_send从SD卡(或其他地方)发送文件,并将内容类型标头设置为带有httpd_resp_set_type"image/jpeg"。所以,就像:

代码语言:javascript
复制
static const httpd_uri_t img_example = {
    .uri       = "/img/example.jpg",
    .method    = HTTP_GET,
    .handler   = img_example_get_handler,
    .user_ctx  = NULL 
};

static esp_err_t img_example_get_handler(httpd_req_t *req)
{
  // 1. get a pointer to your image file
  // 2. httpd_resp_set_type to set the correct content type header
  //    esp_err_t httpd_resp_set_type(httpd_req_t *r, const char *type)
  //      Parameters
  //        [in] r: The request being responded to
  //        [in] type: The Content Type of the response
  // 3. httpd_resp_send to send the response, with the image file as buf
  //    esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len)
  //      Parameters
  //        [in] r: The request being responded to
  //        [in] buf: Buffer from where the content is to be fetched
  //        [in] buf_len: Length of the buffer, HTTPD_RESP_USE_STRLEN to use strlen()

  return ESP_OK;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70819297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档