修改ESP32CAM的示例CameraWebServer里的camera_index.h的方法
在这里,默认你已经会使用Arduino IDE或者PlatformIO通过烧录底座对ESP32CAM(如下图)进行烧录,并能通过浏览器对其进行访问。
我们访问到下图的界面时,不禁有个疑问,这个界面是如何生成的,如果我要修改这个界面要怎么办?本文就是提供了修改这个访问界面的方法
1. ESP32CAM的访问界面是如何产生的
这个界面是HTML页面,Arduino IDE通过对下图中的camera_index.h的编译而生成的。
2. camera_index.h为什么我们常见的html页面代码不一样
当我们打开camera_index.h时,发现其内容如下,三个数组分别对应的是三种不同型号摄像头不同的设置界面。其中的数组部分就是html代码部分,这部分代码与app_httpd.cpp交互来实现对摄像头的各种设置的。只不过在此处,为了方便ESP32等单片机访问,html代码通过gzip压缩成了16进制的数据。
#define index_ov2640_html_gz_len 6787
const uint8_t index_ov2640_html_gz[] = {
0x1F, 0x8B, 0x08, 0x08, 0x23, 0xFC, 0x69, 0x5E, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, 0x6F, 0x76, 0x32, 0x36, 0x34, 0x30, 0x2E, 0x68, 0x74, 0x6D,
0x6C, 0x00, 0xED, 0x3D, 0x6B, 0x73, 0xDB, 0x46, 0x92, 0xDF, 0xFD, 0x2B, 0x60, 0x24, 0x6B, 0x92, 0x25, 0x92, 0x22, 0x29, 0x4A, 0x96, 0x15, 0x89, 0x3E, 0x5B,
......
};
//File: index_ov3660.html.gz, Size: 8887
#define index_ov3660_html_gz_len 8887
const uint8_t index_ov3660_html_gz[] = {
0x1F, 0x8B, 0x08, 0x08, 0xA3, 0xFA, 0x69, 0x5E, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, 0x6F, 0x76, 0x33, 0x36, 0x36, 0x30, 0x2E, 0x68, 0x74, 0x6D,
0x6C, 0x00, 0xED, 0x3D, 0x69, 0x73, 0xDB, 0x46, 0xB2, 0xDF, 0xFD, 0x2B, 0x60, 0x24, 0x6B, 0x51, 0x65, 0x91, 0xE2, 0xAD, 0x23, 0x12, 0xFD, 0x6C, 0x59, 0xB1,
......
};
//File: index_ov5640.html.gz, Size: 9124
#define index_ov5640_html_gz_len 9124
const uint8_t index_ov5640_html_gz[] = {
0x1F, 0x8B, 0x08, 0x08, 0xD9, 0x6C, 0x6A, 0x5E, 0x00, 0x03, 0x69, 0x6E, 0x64, 0x65, 0x78, 0x5F, 0x6F, 0x76, 0x35, 0x36, 0x34, 0x30, 0x2E, 0x68, 0x74, 0x6D,
0x6C, 0x00, 0xED, 0x3D, 0x6B, 0x77, 0xDB, 0xB6, 0x92, 0xDF, 0xF3, 0x2B, 0x18, 0xF5, 0x6E, 0x24, 0x9F, 0x58, 0xB6, 0xA8, 0x97, 0x1F, 0xB1, 0x95, 0x4D, 0x1C,
......
};
3. 怎么对html界面进行修改
我们应该可以想到基本思路,就是:
- 把camera_index.h十六进制数组部分的内容转换成html
- 对html代码进行编辑
- 再把编辑后的html代码转换成十六进制数组
- 把修改的部分替换掉原来的数组
接下来就按照上面的方法对,html界面进行修改,我想在界面上加上OTA上传固件的几个按钮
- 因为我使用的摄像头是OV2640,我只对camera_index.h的第一段数组进行修改,其它两段保持不变,下面要用到一个重要的工具CyberChef,它可以把十六进制数组形式存储的gzip内容转换成html,把数组部分的内容复制到Input文本框,再Output文本框已经可以看到html代码,注意只复制十六位数组数据,数组名之类的内容不要复制。
- 把html代码内容保存为一个html文件,这里已经可以通过浏览器看到这个文件的页面和前面的图片“访问界面”一模一样,这里就不做重复。
因为我要再这个界面里加上传固件,我要加上两个按键和一个文本框,其中两个按键是“打开文件”,“Update",文本框内容是:点update上传固件。其html代码如下,再刚才保存的html文件内找位置加上就可以了。
<div>
<div class="toggle-section-label">Firmware</div>
<button type="button">Select File</button>
<button type="button">Update</button>
<div>点update上传固件</div>
</div>
修改后的html文件已经上传,想参考的可以下载
-
接下面还要再利用一次CyberChel,直接点这个链接CyberChef html to hex会直接进入转换成十六进制的配置,你也可以按照下图自己配置
-
复制Output文本框的内容(除了第一个逗号),放到一个txt文件里,将它命名为array.txt. 接下来对这个文件进行处理,主要处理内容:
求出元素个数
按原来的camera_index.h的数组把数据格式美化一下。
用下面的python代码处理,把array.txt和python代码放到一个目录里
def process_hex_file(input_file, output_file):
try:
# 打开输入文件并读取内容
with open(input_file, 'r') as f:
hex_data = f.read()
# 去掉文件中的空格、换行符和逗号
hex_data = hex_data.replace(' ', '').replace('\n', '').replace(',', '')
# 删除 0x 前缀以正确计算元素个数
hex_data_cleaned = hex_data.replace('0x', '')
element_count = len(hex_data_cleaned) // 2 # 每两个字符表示一个字节
# 将数据分组为每个字节(两个字符为一组),并添加 0x 前缀,确保字母为大写
bytes_data = [f"0x{hex_data_cleaned[i:i+2].upper()}" for i in range(0, len(hex_data_cleaned), 2)]
# 每16个字节换行,并用逗号分隔,确保每行第一个元素前加空格
formatted_data = '\n'.join(
[' ' + ', '.join(bytes_data[i:i+16]) + ',' for i in range(0, len(bytes_data), 16)]
)
# 删除整个数组的最后一个逗号
if formatted_data.endswith(','):
formatted_data = formatted_data[:-1]
# 将格式化后的数据写入新文件
with open(output_file, 'w') as f:
f.write(formatted_data)
# 打印十六进制数据元素个数
print(f"十六进制数据元素个数: {element_count}")
print(f"已保存到文件: {output_file}")
except Exception as e:
print(f"处理文件时出错: {e}")
# 输入文件和输出文件路径
input_file = 'array.txt' # 替换为实际文件路径
output_file = 'copytocameraindex.txt'
# 调用函数
process_hex_file(input_file, output_file)
运行python代码里会出现如下内容:
十六进制数据元素个数: 7006
已保存到文件: copytocameraindex.txt
对camera_index.h进行修改,注意只修改对应摄像头型号的内容,其它摄像头的内容保持不变。
- 将原来的camera_index.h里的
#define index_ov2640_html_gz_len 6787
数字替换为打印出来的的元素个数7006。 - 最后会生成一个文件copytocameraindex.txt,用这个文件里的内容替换掉原来的camera_index.h内OV2640数组的相应的内容。
修改后内容如下。
//File: index_ov2640.html.gz, Size: 7006
#define index_ov2640_html_gz_len 7006
const uint8_t index_ov2640_html_gz[] = {
0x1F, 0x8B, 0x08, 0x00, 0x0C, 0xCB, 0xF8, 0x67, 0x00, 0xFF, 0xED, 0x5D, 0x5B, 0x73, 0xDB, 0x46,
0x96, 0x7E, 0x9E, 0xA9, 0x9A, 0xFF, 0x00, 0x33, 0x19, 0x93, 0x2A, 0x93, 0x94, 0x48, 0x29, 0xB2,
0xA3, 0x91, 0xE8, 0xF5, 0x45, 0xB6, 0x53, 0x1B, 0x27, 0x99, 0x38, 0xB7, 0xA9, 0xA9, 0x29, 0x07,
0x24, 0x9B, 0x24, 0x62, 0x10, 0xE0, 0x00, 0xA0, 0x44, 0x25, 0xA5, 0x97, 0xDD, 0xB7, 0xFD, 0x03,
0xFB, 0xB0, 0x2F, 0xFB, 0x2B, 0xB6, 0xF6, 0xF6, 0xB4, 0xFB, 0x57, 0x66, 0x6B, 0xFF, 0xC6, 0x7C,
0xA7, 0x2F, 0x40, 0x03, 0x68, 0x5C, 0x48, 0xCA, 0x94, 0x26, 0x33, 0x24, 0x8B, 0x04, 0x1B, 0xDD,
0xA7, 0x4F, 0x9F, 0x5B, 0x9F, 0x3E, 0x7D, 0xC1, 0xE9, 0xBD, 0xB1, 0x3F, 0x8A, 0xAE, 0x16, 0xCC,
0x9A, 0x45, 0x73, 0x77, 0xF0, 0xAB, 0x5F, 0x9E, 0xCA, 0x5F, 0x0B, 0xAF, 0xD3, 0x19, 0xB3, 0xC7,
.....
};
修改完成后的界面
可以看到最下面的两个按键和一个文本框。具体的上传的代码和界面修改无关,这里就不展示了。