index_2640.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. #include <Arduino.h>
  2. #define new_index_len 27740
  3. char new_index[] = "<!doctype html>\n"
  4. "<html>\n"
  5. " <head>\n"
  6. " <meta charset=\"utf-8\">\n"
  7. " <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n"
  8. " <title>ESP32 OV2460</title>\n"
  9. " <style>\n"
  10. " body {\n"
  11. " font-family: Arial,Helvetica,sans-serif;\n"
  12. " background: #181818;\n"
  13. " color: #EFEFEF;\n"
  14. " font-size: 16px\n"
  15. " }\n"
  16. "\n"
  17. " h2 {\n"
  18. " font-size: 18px\n"
  19. " }\n"
  20. "\n"
  21. " section.main {\n"
  22. " display: flex\n"
  23. " }\n"
  24. "\n"
  25. " #menu,section.main {\n"
  26. " flex-direction: column\n"
  27. " }\n"
  28. "\n"
  29. " #menu {\n"
  30. " display: none;\n"
  31. " flex-wrap: nowrap;\n"
  32. " min-width: 340px;\n"
  33. " background: #363636;\n"
  34. " padding: 8px;\n"
  35. " border-radius: 4px;\n"
  36. " margin-top: -10px;\n"
  37. " margin-right: 10px;\n"
  38. " }\n"
  39. "\n"
  40. " #content {\n"
  41. " display: flex;\n"
  42. " flex-wrap: wrap;\n"
  43. " align-items: stretch\n"
  44. " }\n"
  45. "\n"
  46. " figure {\n"
  47. " padding: 0px;\n"
  48. " margin: 0;\n"
  49. " -webkit-margin-before: 0;\n"
  50. " margin-block-start: 0;\n"
  51. " -webkit-margin-after: 0;\n"
  52. " margin-block-end: 0;\n"
  53. " -webkit-margin-start: 0;\n"
  54. " margin-inline-start: 0;\n"
  55. " -webkit-margin-end: 0;\n"
  56. " margin-inline-end: 0\n"
  57. " }\n"
  58. "\n"
  59. " figure img {\n"
  60. " display: block;\n"
  61. " width: 100%;\n"
  62. " height: auto;\n"
  63. " border-radius: 4px;\n"
  64. " margin-top: 8px;\n"
  65. " }\n"
  66. "\n"
  67. " @media (min-width: 800px) and (orientation:landscape) {\n"
  68. " #content {\n"
  69. " display:flex;\n"
  70. " flex-wrap: nowrap;\n"
  71. " align-items: stretch\n"
  72. " }\n"
  73. "\n"
  74. " figure img {\n"
  75. " display: block;\n"
  76. " max-width: 100%;\n"
  77. " max-height: calc(100vh - 40px);\n"
  78. " width: auto;\n"
  79. " height: auto\n"
  80. " }\n"
  81. "\n"
  82. " figure {\n"
  83. " padding: 0 0 0 0px;\n"
  84. " margin: 0;\n"
  85. " -webkit-margin-before: 0;\n"
  86. " margin-block-start: 0;\n"
  87. " -webkit-margin-after: 0;\n"
  88. " margin-block-end: 0;\n"
  89. " -webkit-margin-start: 0;\n"
  90. " margin-inline-start: 0;\n"
  91. " -webkit-margin-end: 0;\n"
  92. " margin-inline-end: 0\n"
  93. " }\n"
  94. " }\n"
  95. "\n"
  96. " section#buttons {\n"
  97. " display: flex;\n"
  98. " flex-wrap: nowrap;\n"
  99. " justify-content: space-between\n"
  100. " }\n"
  101. "\n"
  102. " #nav-toggle {\n"
  103. " cursor: pointer;\n"
  104. " display: block\n"
  105. " }\n"
  106. "\n"
  107. " #nav-toggle-cb {\n"
  108. " outline: 0;\n"
  109. " opacity: 0;\n"
  110. " width: 0;\n"
  111. " height: 0\n"
  112. " }\n"
  113. "\n"
  114. " #nav-toggle-cb:checked+#menu {\n"
  115. " display: flex\n"
  116. " }\n"
  117. "\n"
  118. " .input-group {\n"
  119. " display: flex;\n"
  120. " flex-wrap: nowrap;\n"
  121. " line-height: 22px;\n"
  122. " margin: 5px 0\n"
  123. " }\n"
  124. "\n"
  125. " .input-group>label {\n"
  126. " display: inline-block;\n"
  127. " padding-right: 10px;\n"
  128. " min-width: 47%\n"
  129. " }\n"
  130. "\n"
  131. " .input-group input,.input-group select {\n"
  132. " flex-grow: 1\n"
  133. " }\n"
  134. "\n"
  135. " .range-max,.range-min {\n"
  136. " display: inline-block;\n"
  137. " padding: 0 5px\n"
  138. " }\n"
  139. "\n"
  140. " button {\n"
  141. " display: block;\n"
  142. " margin: 5px;\n"
  143. " padding: 0 12px;\n"
  144. " border: 0;\n"
  145. " line-height: 28px;\n"
  146. " cursor: pointer;\n"
  147. " color: #fff;\n"
  148. " background: #ff3034;\n"
  149. " border-radius: 5px;\n"
  150. " font-size: 16px;\n"
  151. " outline: 0\n"
  152. " }\n"
  153. "\n"
  154. " button:hover {\n"
  155. " background: #ff494d\n"
  156. " }\n"
  157. "\n"
  158. " button:active {\n"
  159. " background: #f21c21\n"
  160. " }\n"
  161. "\n"
  162. " button.disabled {\n"
  163. " cursor: default;\n"
  164. " background: #a0a0a0\n"
  165. " }\n"
  166. "\n"
  167. " input[type=range] {\n"
  168. " -webkit-appearance: none;\n"
  169. " width: 100%;\n"
  170. " height: 22px;\n"
  171. " background: #363636;\n"
  172. " cursor: pointer;\n"
  173. " margin: 0\n"
  174. " }\n"
  175. "\n"
  176. " input[type=range]:focus {\n"
  177. " outline: 0\n"
  178. " }\n"
  179. "\n"
  180. " input[type=range]::-webkit-slider-runnable-track {\n"
  181. " width: 100%;\n"
  182. " height: 2px;\n"
  183. " cursor: pointer;\n"
  184. " background: #EFEFEF;\n"
  185. " border-radius: 0;\n"
  186. " border: 0 solid #EFEFEF\n"
  187. " }\n"
  188. "\n"
  189. " input[type=range]::-webkit-slider-thumb {\n"
  190. " border: 1px solid rgba(0,0,30,0);\n"
  191. " height: 22px;\n"
  192. " width: 22px;\n"
  193. " border-radius: 50px;\n"
  194. " background: #ff3034;\n"
  195. " cursor: pointer;\n"
  196. " -webkit-appearance: none;\n"
  197. " margin-top: -11.5px\n"
  198. " }\n"
  199. "\n"
  200. " input[type=range]:focus::-webkit-slider-runnable-track {\n"
  201. " background: #EFEFEF\n"
  202. " }\n"
  203. "\n"
  204. " input[type=range]::-moz-range-track {\n"
  205. " width: 100%;\n"
  206. " height: 2px;\n"
  207. " cursor: pointer;\n"
  208. " background: #EFEFEF;\n"
  209. " border-radius: 0;\n"
  210. " border: 0 solid #EFEFEF\n"
  211. " }\n"
  212. "\n"
  213. " input[type=range]::-moz-range-thumb {\n"
  214. " border: 1px solid rgba(0,0,30,0);\n"
  215. " height: 22px;\n"
  216. " width: 22px;\n"
  217. " border-radius: 50px;\n"
  218. " background: #ff3034;\n"
  219. " cursor: pointer\n"
  220. " }\n"
  221. "\n"
  222. " input[type=range]::-ms-track {\n"
  223. " width: 100%;\n"
  224. " height: 2px;\n"
  225. " cursor: pointer;\n"
  226. " background: 0 0;\n"
  227. " border-color: transparent;\n"
  228. " color: transparent\n"
  229. " }\n"
  230. "\n"
  231. " input[type=range]::-ms-fill-lower {\n"
  232. " background: #EFEFEF;\n"
  233. " border: 0 solid #EFEFEF;\n"
  234. " border-radius: 0\n"
  235. " }\n"
  236. "\n"
  237. " input[type=range]::-ms-fill-upper {\n"
  238. " background: #EFEFEF;\n"
  239. " border: 0 solid #EFEFEF;\n"
  240. " border-radius: 0\n"
  241. " }\n"
  242. "\n"
  243. " input[type=range]::-ms-thumb {\n"
  244. " border: 1px solid rgba(0,0,30,0);\n"
  245. " height: 22px;\n"
  246. " width: 22px;\n"
  247. " border-radius: 50px;\n"
  248. " background: #ff3034;\n"
  249. " cursor: pointer;\n"
  250. " height: 2px\n"
  251. " }\n"
  252. "\n"
  253. " input[type=range]:focus::-ms-fill-lower {\n"
  254. " background: #EFEFEF\n"
  255. " }\n"
  256. "\n"
  257. " input[type=range]:focus::-ms-fill-upper {\n"
  258. " background: #363636\n"
  259. " }\n"
  260. "\n"
  261. " .switch {\n"
  262. " display: block;\n"
  263. " position: relative;\n"
  264. " line-height: 22px;\n"
  265. " font-size: 16px;\n"
  266. " height: 22px\n"
  267. " }\n"
  268. "\n"
  269. " .switch input {\n"
  270. " outline: 0;\n"
  271. " opacity: 0;\n"
  272. " width: 0;\n"
  273. " height: 0\n"
  274. " }\n"
  275. "\n"
  276. " .slider {\n"
  277. " width: 50px;\n"
  278. " height: 22px;\n"
  279. " border-radius: 22px;\n"
  280. " cursor: pointer;\n"
  281. " background-color: grey\n"
  282. " }\n"
  283. "\n"
  284. " .slider,.slider:before {\n"
  285. " display: inline-block;\n"
  286. " transition: .4s\n"
  287. " }\n"
  288. "\n"
  289. " .slider:before {\n"
  290. " position: relative;\n"
  291. " content: \"\";\n"
  292. " border-radius: 50%;\n"
  293. " height: 16px;\n"
  294. " width: 16px;\n"
  295. " left: 4px;\n"
  296. " top: 3px;\n"
  297. " background-color: #fff\n"
  298. " }\n"
  299. "\n"
  300. " input:checked+.slider {\n"
  301. " background-color: #ff3034\n"
  302. " }\n"
  303. "\n"
  304. " input:checked+.slider:before {\n"
  305. " -webkit-transform: translateX(26px);\n"
  306. " transform: translateX(26px)\n"
  307. " }\n"
  308. "\n"
  309. " select {\n"
  310. " border: 1px solid #363636;\n"
  311. " font-size: 14px;\n"
  312. " height: 22px;\n"
  313. " outline: 0;\n"
  314. " border-radius: 5px\n"
  315. " }\n"
  316. "\n"
  317. " .image-container {\n"
  318. " position: relative;\n"
  319. " min-width: 160px\n"
  320. " }\n"
  321. "\n"
  322. " .close {\n"
  323. " position: absolute;\n"
  324. " right: 5px;\n"
  325. " top: 5px;\n"
  326. " background: #ff3034;\n"
  327. " width: 16px;\n"
  328. " height: 16px;\n"
  329. " border-radius: 100px;\n"
  330. " color: #fff;\n"
  331. " text-align: center;\n"
  332. " line-height: 18px;\n"
  333. " cursor: pointer\n"
  334. " }\n"
  335. "\n"
  336. " .hidden {\n"
  337. " display: none\n"
  338. " }\n"
  339. " </style>\n"
  340. " </head>\n"
  341. " <body>\n"
  342. " <section class=\"main\">\n"
  343. " <div id=\"logo\">\n"
  344. " <label for=\"nav-toggle-cb\" id=\"nav-toggle\">&#9776;&nbsp;&nbsp;Toggle OV2640 settings</label>\n"
  345. " </div>\n"
  346. " <div id=\"content\">\n"
  347. " <div id=\"sidebar\">\n"
  348. " <input type=\"checkbox\" id=\"nav-toggle-cb\" checked=\"checked\">\n"
  349. " <nav id=\"menu\">\n"
  350. " <div class=\"input-group\" id=\"framesize-group\">\n"
  351. " <label for=\"framesize\">Resolution</label>\n"
  352. " <select id=\"framesize\" class=\"default-action\">\n"
  353. " <option value=\"10\">UXGA(1600x1200)</option>\n"
  354. " <option value=\"9\">SXGA(1280x1024)</option>\n"
  355. " <option value=\"8\">XGA(1024x768)</option>\n"
  356. " <option value=\"7\">SVGA(800x600)</option>\n"
  357. " <option value=\"6\">VGA(640x480)</option>\n"
  358. " <option value=\"5\" selected=\"selected\">CIF(400x296)</option>\n"
  359. " <option value=\"4\">QVGA(320x240)</option>\n"
  360. " <option value=\"3\">HQVGA(240x176)</option>\n"
  361. " <option value=\"0\">QQVGA(160x120)</option>\n"
  362. " </select>\n"
  363. " </div>\n"
  364. " <div class=\"input-group\" id=\"quality-group\">\n"
  365. " <label for=\"quality\">Quality</label>\n"
  366. " <div class=\"range-min\">10</div>\n"
  367. " <input type=\"range\" id=\"quality\" min=\"10\" max=\"63\" value=\"10\" class=\"default-action\">\n"
  368. " <div class=\"range-max\">63</div>\n"
  369. " </div>\n"
  370. " <div class=\"input-group\" id=\"brightness-group\">\n"
  371. " <label for=\"brightness\">Brightness</label>\n"
  372. " <div class=\"range-min\">-2</div>\n"
  373. " <input type=\"range\" id=\"brightness\" min=\"-2\" max=\"2\" value=\"0\" class=\"default-action\">\n"
  374. " <div class=\"range-max\">2</div>\n"
  375. " </div>\n"
  376. " <div class=\"input-group\" id=\"contrast-group\">\n"
  377. " <label for=\"contrast\">Contrast</label>\n"
  378. " <div class=\"range-min\">-2</div>\n"
  379. " <input type=\"range\" id=\"contrast\" min=\"-2\" max=\"2\" value=\"0\" class=\"default-action\">\n"
  380. " <div class=\"range-max\">2</div>\n"
  381. " </div>\n"
  382. " <div class=\"input-group\" id=\"saturation-group\">\n"
  383. " <label for=\"saturation\">Saturation</label>\n"
  384. " <div class=\"range-min\">-2</div>\n"
  385. " <input type=\"range\" id=\"saturation\" min=\"-2\" max=\"2\" value=\"0\" class=\"default-action\">\n"
  386. " <div class=\"range-max\">2</div>\n"
  387. " </div>\n"
  388. " <div class=\"input-group\" id=\"special_effect-group\">\n"
  389. " <label for=\"special_effect\">Special Effect</label>\n"
  390. " <select id=\"special_effect\" class=\"default-action\">\n"
  391. " <option value=\"0\" selected=\"selected\">No Effect</option>\n"
  392. " <option value=\"1\">Negative</option>\n"
  393. " <option value=\"2\">Grayscale</option>\n"
  394. " <option value=\"3\">Red Tint</option>\n"
  395. " <option value=\"4\">Green Tint</option>\n"
  396. " <option value=\"5\">Blue Tint</option>\n"
  397. " <option value=\"6\">Sepia</option>\n"
  398. " </select>\n"
  399. " </div>\n"
  400. " <div class=\"input-group\" id=\"awb-group\">\n"
  401. " <label for=\"awb\">AWB</label>\n"
  402. " <div class=\"switch\">\n"
  403. " <input id=\"awb\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  404. " <label class=\"slider\" for=\"awb\"></label>\n"
  405. " </div>\n"
  406. " </div>\n"
  407. " <div class=\"input-group\" id=\"awb_gain-group\">\n"
  408. " <label for=\"awb_gain\">AWB Gain</label>\n"
  409. " <div class=\"switch\">\n"
  410. " <input id=\"awb_gain\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  411. " <label class=\"slider\" for=\"awb_gain\"></label>\n"
  412. " </div>\n"
  413. " </div>\n"
  414. " <div class=\"input-group\" id=\"wb_mode-group\">\n"
  415. " <label for=\"wb_mode\">WB Mode</label>\n"
  416. " <select id=\"wb_mode\" class=\"default-action\">\n"
  417. " <option value=\"0\" selected=\"selected\">Auto</option>\n"
  418. " <option value=\"1\">Sunny</option>\n"
  419. " <option value=\"2\">Cloudy</option>\n"
  420. " <option value=\"3\">Office</option>\n"
  421. " <option value=\"4\">Home</option>\n"
  422. " </select>\n"
  423. " </div>\n"
  424. " <div class=\"input-group\" id=\"aec-group\">\n"
  425. " <label for=\"aec\">AEC SENSOR</label>\n"
  426. " <div class=\"switch\">\n"
  427. " <input id=\"aec\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  428. " <label class=\"slider\" for=\"aec\"></label>\n"
  429. " </div>\n"
  430. " </div>\n"
  431. " <div class=\"input-group\" id=\"aec2-group\">\n"
  432. " <label for=\"aec2\">AEC DSP</label>\n"
  433. " <div class=\"switch\">\n"
  434. " <input id=\"aec2\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  435. " <label class=\"slider\" for=\"aec2\"></label>\n"
  436. " </div>\n"
  437. " </div>\n"
  438. " <div class=\"input-group\" id=\"ae_level-group\">\n"
  439. " <label for=\"ae_level\">AE Level</label>\n"
  440. " <div class=\"range-min\">-2</div>\n"
  441. " <input type=\"range\" id=\"ae_level\" min=\"-2\" max=\"2\" value=\"0\" class=\"default-action\">\n"
  442. " <div class=\"range-max\">2</div>\n"
  443. " </div>\n"
  444. " <div class=\"input-group\" id=\"aec_value-group\">\n"
  445. " <label for=\"aec_value\">Exposure</label>\n"
  446. " <div class=\"range-min\">0</div>\n"
  447. " <input type=\"range\" id=\"aec_value\" min=\"0\" max=\"1200\" value=\"204\" class=\"default-action\">\n"
  448. " <div class=\"range-max\">1200</div>\n"
  449. " </div>\n"
  450. " <div class=\"input-group\" id=\"agc-group\">\n"
  451. " <label for=\"agc\">AGC</label>\n"
  452. " <div class=\"switch\">\n"
  453. " <input id=\"agc\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  454. " <label class=\"slider\" for=\"agc\"></label>\n"
  455. " </div>\n"
  456. " </div>\n"
  457. " <div class=\"input-group hidden\" id=\"agc_gain-group\">\n"
  458. " <label for=\"agc_gain\">Gain</label>\n"
  459. " <div class=\"range-min\">1x</div>\n"
  460. " <input type=\"range\" id=\"agc_gain\" min=\"0\" max=\"30\" value=\"5\" class=\"default-action\">\n"
  461. " <div class=\"range-max\">31x</div>\n"
  462. " </div>\n"
  463. " <div class=\"input-group\" id=\"gainceiling-group\">\n"
  464. " <label for=\"gainceiling\">Gain Ceiling</label>\n"
  465. " <div class=\"range-min\">2x</div>\n"
  466. " <input type=\"range\" id=\"gainceiling\" min=\"0\" max=\"6\" value=\"0\" class=\"default-action\">\n"
  467. " <div class=\"range-max\">128x</div>\n"
  468. " </div>\n"
  469. " <div class=\"input-group\" id=\"bpc-group\">\n"
  470. " <label for=\"bpc\">BPC</label>\n"
  471. " <div class=\"switch\">\n"
  472. " <input id=\"bpc\" type=\"checkbox\" class=\"default-action\">\n"
  473. " <label class=\"slider\" for=\"bpc\"></label>\n"
  474. " </div>\n"
  475. " </div>\n"
  476. " <div class=\"input-group\" id=\"wpc-group\">\n"
  477. " <label for=\"wpc\">WPC</label>\n"
  478. " <div class=\"switch\">\n"
  479. " <input id=\"wpc\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  480. " <label class=\"slider\" for=\"wpc\"></label>\n"
  481. " </div>\n"
  482. " </div>\n"
  483. " <div class=\"input-group\" id=\"raw_gma-group\">\n"
  484. " <label for=\"raw_gma\">Raw GMA</label>\n"
  485. " <div class=\"switch\">\n"
  486. " <input id=\"raw_gma\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  487. " <label class=\"slider\" for=\"raw_gma\"></label>\n"
  488. " </div>\n"
  489. " </div>\n"
  490. " <div class=\"input-group\" id=\"lenc-group\">\n"
  491. " <label for=\"lenc\">Lens Correction</label>\n"
  492. " <div class=\"switch\">\n"
  493. " <input id=\"lenc\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  494. " <label class=\"slider\" for=\"lenc\"></label>\n"
  495. " </div>\n"
  496. " </div>\n"
  497. " <div class=\"input-group\" id=\"hmirror-group\">\n"
  498. " <label for=\"hmirror\">H-Mirror</label>\n"
  499. " <div class=\"switch\">\n"
  500. " <input id=\"hmirror\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  501. " <label class=\"slider\" for=\"hmirror\"></label>\n"
  502. " </div>\n"
  503. " </div>\n"
  504. " <div class=\"input-group\" id=\"vflip-group\">\n"
  505. " <label for=\"vflip\">V-Flip</label>\n"
  506. " <div class=\"switch\">\n"
  507. " <input id=\"vflip\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  508. " <label class=\"slider\" for=\"vflip\"></label>\n"
  509. " </div>\n"
  510. " </div>\n"
  511. " <div class=\"input-group\" id=\"dcw-group\">\n"
  512. " <label for=\"dcw\">DCW (Downsize EN)</label>\n"
  513. " <div class=\"switch\">\n"
  514. " <input id=\"dcw\" type=\"checkbox\" class=\"default-action\" checked=\"checked\">\n"
  515. " <label class=\"slider\" for=\"dcw\"></label>\n"
  516. " </div>\n"
  517. " </div>\n"
  518. " <div class=\"input-group\" id=\"colorbar-group\">\n"
  519. " <label for=\"colorbar\">Color Bar</label>\n"
  520. " <div class=\"switch\">\n"
  521. " <input id=\"colorbar\" type=\"checkbox\" class=\"default-action\">\n"
  522. " <label class=\"slider\" for=\"colorbar\"></label>\n"
  523. " </div>\n"
  524. " </div>\n"
  525. " <div class=\"input-group\" id=\"face_detect-group\">\n"
  526. " <label for=\"face_detect\">Face Detection</label>\n"
  527. " <div class=\"switch\">\n"
  528. " <input id=\"face_detect\" type=\"checkbox\" class=\"default-action\">\n"
  529. " <label class=\"slider\" for=\"face_detect\"></label>\n"
  530. " </div>\n"
  531. " </div>\n"
  532. " <div class=\"input-group\" id=\"face_recognize-group\">\n"
  533. " <label for=\"face_recognize\">Face Recognition</label>\n"
  534. " <div class=\"switch\">\n"
  535. " <input id=\"face_recognize\" type=\"checkbox\" class=\"default-action\">\n"
  536. " <label class=\"slider\" for=\"face_recognize\"></label>\n"
  537. " </div>\n"
  538. " </div>\n"
  539. " <section id=\"buttons\">\n"
  540. " <button id=\"get-still\">Get Still</button>\n"
  541. " <button id=\"toggle-stream\">Start Stream</button>\n"
  542. " <button id=\"face_enroll\" class=\"disabled\" disabled=\"disabled\">Enroll Face</button>\n"
  543. " </section>\n"
  544. " </nav>\n"
  545. " </div>\n"
  546. " <figure>\n"
  547. " <div id=\"stream-container\" class=\"image-container hidden\">\n"
  548. " <div class=\"close\" id=\"close-stream\">×</div>\n"
  549. " <img id=\"stream\" src=\"\">\n"
  550. " </div>\n"
  551. " </figure>\n"
  552. " </div>\n"
  553. " </section>\n"
  554. " <script>\n"
  555. "document.addEventListener('DOMContentLoaded', function (event) {\n"
  556. " var baseHost = document.location.origin\n"
  557. " var streamUrl = baseHost + ':81'\n"
  558. "\n"
  559. " const hide = el => {\n"
  560. " el.classList.add('hidden')\n"
  561. " }\n"
  562. " const show = el => {\n"
  563. " el.classList.remove('hidden')\n"
  564. " }\n"
  565. "\n"
  566. " const disable = el => {\n"
  567. " el.classList.add('disabled')\n"
  568. " el.disabled = true\n"
  569. " }\n"
  570. "\n"
  571. " const enable = el => {\n"
  572. " el.classList.remove('disabled')\n"
  573. " el.disabled = false\n"
  574. " }\n"
  575. "\n"
  576. " const updateValue = (el, value, updateRemote) => {\n"
  577. " updateRemote = updateRemote == null ? true : updateRemote\n"
  578. " let initialValue\n"
  579. " if (el.type === 'checkbox') {\n"
  580. " initialValue = el.checked\n"
  581. " value = !!value\n"
  582. " el.checked = value\n"
  583. " } else {\n"
  584. " initialValue = el.value\n"
  585. " el.value = value\n"
  586. " }\n"
  587. "\n"
  588. " if (updateRemote && initialValue !== value) {\n"
  589. " updateConfig(el);\n"
  590. " } else if(!updateRemote){\n"
  591. " if(el.id === \"aec\"){\n"
  592. " value ? hide(exposure) : show(exposure)\n"
  593. " } else if(el.id === \"agc\"){\n"
  594. " if (value) {\n"
  595. " show(gainCeiling)\n"
  596. " hide(agcGain)\n"
  597. " } else {\n"
  598. " hide(gainCeiling)\n"
  599. " show(agcGain)\n"
  600. " }\n"
  601. " } else if(el.id === \"awb_gain\"){\n"
  602. " value ? show(wb) : hide(wb)\n"
  603. " } else if(el.id === \"face_recognize\"){\n"
  604. " value ? enable(enrollButton) : disable(enrollButton)\n"
  605. " }\n"
  606. " }\n"
  607. " }\n"
  608. "\n"
  609. " function updateConfig (el) {\n"
  610. " let value\n"
  611. " switch (el.type) {\n"
  612. " case 'checkbox':\n"
  613. " value = el.checked ? 1 : 0\n"
  614. " break\n"
  615. " case 'range':\n"
  616. " case 'select-one':\n"
  617. " value = el.value\n"
  618. " break\n"
  619. " case 'button':\n"
  620. " case 'submit':\n"
  621. " value = '1'\n"
  622. " break\n"
  623. " default:\n"
  624. " return\n"
  625. " }\n"
  626. "\n"
  627. " const query = `${baseHost}/control?var=${el.id}&val=${value}`\n"
  628. "\n"
  629. " fetch(query)\n"
  630. " .then(response => {\n"
  631. " console.log(`request to ${query} finished, status: ${response.status}`)\n"
  632. " })\n"
  633. " }\n"
  634. "\n"
  635. " document\n"
  636. " .querySelectorAll('.close')\n"
  637. " .forEach(el => {\n"
  638. " el.onclick = () => {\n"
  639. " hide(el.parentNode)\n"
  640. " }\n"
  641. " })\n"
  642. "\n"
  643. " // read initial values\n"
  644. " fetch(`${baseHost}/status`)\n"
  645. " .then(function (response) {\n"
  646. " return response.json()\n"
  647. " })\n"
  648. " .then(function (state) {\n"
  649. " document\n"
  650. " .querySelectorAll('.default-action')\n"
  651. " .forEach(el => {\n"
  652. " updateValue(el, state[el.id], false)\n"
  653. " })\n"
  654. " })\n"
  655. "\n"
  656. " const view = document.getElementById('stream')\n"
  657. " const viewContainer = document.getElementById('stream-container')\n"
  658. " const stillButton = document.getElementById('get-still')\n"
  659. " const streamButton = document.getElementById('toggle-stream')\n"
  660. " const enrollButton = document.getElementById('face_enroll')\n"
  661. " const closeButton = document.getElementById('close-stream')\n"
  662. "\n"
  663. " const stopStream = () => {\n"
  664. " window.stop();\n"
  665. " streamButton.innerHTML = 'Start Stream'\n"
  666. " }\n"
  667. "\n"
  668. " const startStream = () => {\n"
  669. " view.src = `${streamUrl}/stream`\n"
  670. " show(viewContainer)\n"
  671. " streamButton.innerHTML = 'Stop Stream'\n"
  672. " }\n"
  673. "\n"
  674. " // Attach actions to buttons\n"
  675. " stillButton.onclick = () => {\n"
  676. " stopStream()\n"
  677. " view.src = `${baseHost}/capture?_cb=${Date.now()}`\n"
  678. " show(viewContainer)\n"
  679. " }\n"
  680. "\n"
  681. " closeButton.onclick = () => {\n"
  682. " stopStream()\n"
  683. " hide(viewContainer)\n"
  684. " }\n"
  685. "\n"
  686. " streamButton.onclick = () => {\n"
  687. " const streamEnabled = streamButton.innerHTML === 'Stop Stream'\n"
  688. " if (streamEnabled) {\n"
  689. " stopStream()\n"
  690. " } else {\n"
  691. " startStream()\n"
  692. " }\n"
  693. " }\n"
  694. "\n"
  695. " enrollButton.onclick = () => {\n"
  696. " updateConfig(enrollButton)\n"
  697. " }\n"
  698. "\n"
  699. " // Attach default on change action\n"
  700. " document\n"
  701. " .querySelectorAll('.default-action')\n"
  702. " .forEach(el => {\n"
  703. " el.onchange = () => updateConfig(el)\n"
  704. " })\n"
  705. "\n"
  706. " // Custom actions\n"
  707. " // Gain\n"
  708. " const agc = document.getElementById('agc')\n"
  709. " const agcGain = document.getElementById('agc_gain-group')\n"
  710. " const gainCeiling = document.getElementById('gainceiling-group')\n"
  711. " agc.onchange = () => {\n"
  712. " updateConfig(agc)\n"
  713. " if (agc.checked) {\n"
  714. " show(gainCeiling)\n"
  715. " hide(agcGain)\n"
  716. " } else {\n"
  717. " hide(gainCeiling)\n"
  718. " show(agcGain)\n"
  719. " }\n"
  720. " }\n"
  721. "\n"
  722. " // Exposure\n"
  723. " const aec = document.getElementById('aec')\n"
  724. " const exposure = document.getElementById('aec_value-group')\n"
  725. " aec.onchange = () => {\n"
  726. " updateConfig(aec)\n"
  727. " aec.checked ? hide(exposure) : show(exposure)\n"
  728. " }\n"
  729. "\n"
  730. " // AWB\n"
  731. " const awb = document.getElementById('awb_gain')\n"
  732. " const wb = document.getElementById('wb_mode-group')\n"
  733. " awb.onchange = () => {\n"
  734. " updateConfig(awb)\n"
  735. " awb.checked ? show(wb) : hide(wb)\n"
  736. " }\n"
  737. "\n"
  738. " // Detection and framesize\n"
  739. " const detect = document.getElementById('face_detect')\n"
  740. " const recognize = document.getElementById('face_recognize')\n"
  741. " const framesize = document.getElementById('framesize')\n"
  742. "\n"
  743. " framesize.onchange = () => {\n"
  744. " updateConfig(framesize)\n"
  745. " if (framesize.value > 5) {\n"
  746. " updateValue(detect, false)\n"
  747. " updateValue(recognize, false)\n"
  748. " }\n"
  749. " }\n"
  750. "\n"
  751. " detect.onchange = () => {\n"
  752. " if (framesize.value > 5) {\n"
  753. " alert(\"Please select CIF or lower resolution before enabling this feature!\");\n"
  754. " updateValue(detect, false)\n"
  755. " return;\n"
  756. " }\n"
  757. " updateConfig(detect)\n"
  758. " if (!detect.checked) {\n"
  759. " disable(enrollButton)\n"
  760. " updateValue(recognize, false)\n"
  761. " }\n"
  762. " }\n"
  763. "\n"
  764. " recognize.onchange = () => {\n"
  765. " if (framesize.value > 5) {\n"
  766. " alert(\"Please select CIF or lower resolution before enabling this feature!\");\n"
  767. " updateValue(recognize, false)\n"
  768. " return;\n"
  769. " }\n"
  770. " updateConfig(recognize)\n"
  771. " if (recognize.checked) {\n"
  772. " enable(enrollButton)\n"
  773. " updateValue(detect, true)\n"
  774. " } else {\n"
  775. " disable(enrollButton)\n"
  776. " }\n"
  777. " }\n"
  778. "})\n"
  779. "\n"
  780. " </script>\n"
  781. " </body>\n"
  782. "</html>\n"
  783. ;