Skip to content

Commit

Permalink
config: light mode and special effect
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 7, 2025
1 parent 5c42f60 commit d991016
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 37 deletions.
78 changes: 49 additions & 29 deletions examples/AsyncCam/handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ static const char FRONTPAGE[] = R"EOT(
<body>
<h1>esp32cam AsyncCam example</h1>
<form id="update"><p>
<select name="resolution" required>%resolution%</select>
<select name="resolution">%resolution%</select>
%brightness%
%contrast%
%saturation%
<select name="lightMode" title="light mode">%lightMode%</select>
<select name="specialEffect" title="special effect">%specialEffect%</select>
%hmirror%
%vflip%
<input type="submit" value="update">
Expand Down Expand Up @@ -38,7 +40,7 @@ const $display = document.querySelector("#display");
try {
await fetchText("/update.cgi", {
method: "POST",
body: new URLSearchParams(new FormData($update)),
body: new FormData($update),
});
} catch (err) {
$display.textContent = err.toString();
Expand Down Expand Up @@ -79,30 +81,52 @@ rewriteFrontpage(const esp32cam::Settings& s, const String& var) {
b.print(r);
b.print("</option>");
}
} else if (var == "lightMode") {
#define SHOW_LM(MODE, SYMBOL) \
b.printf("<option value=\"%d\" title=\"%s\"%s>%s</option>", \
static_cast<int>(esp32cam::LightMode::MODE), #MODE, \
s.lightMode == esp32cam::LightMode::MODE ? " selected" : "", SYMBOL)
SHOW_LM(AUTO, "&#x2B55;");
SHOW_LM(SUNNY, "&#x2600;&#xFE0F;");
SHOW_LM(CLOUDY, "&#x2601;&#xFE0F;");
SHOW_LM(OFFICE, "&#x1F3E2;");
SHOW_LM(HOME, "&#x1F3E0;");
#undef SHOW_LM
} else if (var == "specialEffect") {
#define SHOW_SE(MODE, SYMBOL) \
b.printf("<option value=\"%d\" title=\"%s\"%s>%s</option>", \
static_cast<int>(esp32cam::SpecialEffect::MODE), #MODE, \
s.specialEffect == esp32cam::SpecialEffect::MODE ? " selected" : "", SYMBOL)
SHOW_SE(NONE, "&#x1F6AB;");
SHOW_SE(NEGATIVE, "&#x2B1C;");
SHOW_SE(BLACKWHITE, "&#x2B1B;");
SHOW_SE(REDDISH, "&#x1F7E5;");
SHOW_SE(GREENISH, "&#x1F7E9;");
SHOW_SE(BLUISH, "&#x1F7E6;");
SHOW_SE(ANTIQUE, "&#x1F5BC;&#xFE0F;");
#undef SHOW_SE
}

#define SETTING_INT(MEM, MIN, MAX) \
#define SHOW_INT(MEM, MIN, MAX) \
else if (var == #MEM) { \
b.printf("<label>" #MEM "=<input type=\"number\" name=\"" #MEM \
"\" value=\"%d\" min=\"%d\" max=\"%d\"></label>", \
s.MEM, MIN, MAX); \
}

#define SETTING_BOOL(MEM) \
#define SHOW_BOOL(MEM) \
else if (var == #MEM) { \
b.printf("<label><input type=\"checkbox\" name=\"" #MEM "\" value=\"1\"%s>" #MEM "</label>", \
s.MEM ? " checked" : ""); \
}

SETTING_INT(brightness, -2, 2)
SETTING_INT(contrast, -2, 2)
SETTING_INT(saturation, -2, 2)
SETTING_BOOL(hmirror)
SETTING_BOOL(vflip)

#undef SETTING_INT
#undef SETTING_BOOL

SHOW_INT(brightness, -2, 2)
SHOW_INT(contrast, -2, 2)
SHOW_INT(saturation, -2, 2)
SHOW_BOOL(hmirror)
SHOW_BOOL(vflip)
#undef SHOW_INT
#undef SHOW_BOOL
return b;
}

Expand All @@ -116,22 +140,18 @@ handleFrontpage(AsyncWebServerRequest* req) {
static void
handleUpdate(AsyncWebServerRequest* req) {
bool ok = esp32cam::Camera.update([=](esp32cam::Settings& s) {
#define UPDATE(MEM) \
do { \
if constexpr (std::is_same_v<decltype(s.MEM), bool>) { \
s.MEM = req->hasArg(#MEM); \
} else { \
s.MEM = static_cast<decltype(s.MEM)>(req->arg(#MEM).toInt()); \
} \
} while (false)
s.resolution = esp32cam::Resolution(static_cast<int>(req->arg("resolution").toInt()));
UPDATE(brightness);
UPDATE(contrast);
UPDATE(saturation);
UPDATE(hmirror);
UPDATE(vflip);

#undef UPDATE
#define SAVE_BOOL(MEM) s.MEM = req->hasArg(#MEM)
#define SAVE_INT(MEM) s.MEM = decltype(s.MEM)(req->arg(#MEM).toInt())
SAVE_INT(resolution);
SAVE_INT(brightness);
SAVE_INT(contrast);
SAVE_INT(saturation);
SAVE_INT(lightMode);
SAVE_INT(specialEffect);
SAVE_BOOL(hmirror);
SAVE_BOOL(vflip);
#undef SAVE_BOOL
#undef SAVE_INT
});

if (!ok) {
Expand Down
23 changes: 15 additions & 8 deletions src/esp32cam/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ CameraClass::status() const {
result.brightness = sensor->status.brightness;
result.contrast = sensor->status.contrast;
result.saturation = sensor->status.saturation;
result.lightMode = static_cast<LightMode>(sensor->status.wb_mode);
result.specialEffect = static_cast<SpecialEffect>(sensor->status.special_effect);
result.hmirror = sensor->status.hmirror != 0;
result.vflip = sensor->status.vflip != 0;
return result;
Expand All @@ -118,20 +120,21 @@ CameraClass::update(const Settings& settings, int sleepFor) {

#define CHECK_RANGE(MEM, MIN, MAX) \
do { \
if (!(settings.MEM >= MIN && settings.MEM <= MAX)) { \
ESP32CAM_LOG("update " #MEM " %d out of range [%d,%d]", static_cast<int>(settings.MEM), MIN, \
MAX); \
int next = static_cast<int>(settings.MEM); \
if (!(next >= MIN && next <= MAX)) { \
ESP32CAM_LOG("update " #MEM " %d out of range [%d,%d]", next, MIN, MAX); \
return false; \
} \
} while (false)

#define UPDATE(STATUS_MEM, SETTING_MEM, SETTER_TYP) \
do { \
auto prev = sensor->status.STATUS_MEM; \
if (prev != static_cast<decltype(prev)>(settings.SETTING_MEM)) { \
int res = sensor->set_##STATUS_MEM(sensor, static_cast<SETTER_TYP>(settings.SETTING_MEM)); \
ESP32CAM_LOG("update " #STATUS_MEM " %d => %d %s", static_cast<int>(prev), \
static_cast<int>(settings.SETTING_MEM), res == 0 ? "success" : "failure"); \
int prev = static_cast<int>(sensor->status.STATUS_MEM); \
int next = static_cast<int>(settings.SETTING_MEM); \
if (prev != static_cast<int>(settings.SETTING_MEM)) { \
int res = sensor->set_##STATUS_MEM(sensor, static_cast<SETTER_TYP>(next)); \
ESP32CAM_LOG("update " #STATUS_MEM " %d => %d %s", prev, next, \
res == 0 ? "success" : "failure"); \
if (res != 0) { \
return false; \
} \
Expand All @@ -142,11 +145,15 @@ CameraClass::update(const Settings& settings, int sleepFor) {
CHECK_RANGE(brightness, -2, 2);
CHECK_RANGE(contrast, -2, 2);
CHECK_RANGE(saturation, -2, 2);
CHECK_RANGE(lightMode, 0, 4);
CHECK_RANGE(specialEffect, 0, 6);

UPDATE(framesize, resolution.as<framesize_t>(), framesize_t);
UPDATE1(brightness);
UPDATE1(contrast);
UPDATE1(saturation);
UPDATE(wb_mode, lightMode, int);
UPDATE(special_effect, specialEffect, int);
UPDATE1(hmirror);
UPDATE1(vflip);

Expand Down
26 changes: 26 additions & 0 deletions src/esp32cam/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ class Config {
friend class CameraClass;
};

/** @brief Light mode / white balance values. */
enum class LightMode {
AUTO = 0,
SUNNY = 1,
CLOUDY = 2,
OFFICE = 3,
HOME = 4,
};

/** @brief Special effect values. */
enum class SpecialEffect {
NONE = 0,
NEGATIVE = 1,
BLACKWHITE = 2,
REDDISH = 3,
GREENISH = 4,
BLUISH = 5,
ANTIQUE = 6,
};

/** @brief Camera runtime settings. */
struct Settings {
/** @brief Picture resolution. */
Expand All @@ -66,6 +86,12 @@ struct Settings {
/** @brief Image saturation, between -2 and +2. */
int8_t saturation;

/** @brief Image light mode. */
LightMode lightMode;

/** @brief Image special effect. */
SpecialEffect specialEffect;

/** @brief Horizontal flip. */
bool hmirror = false;

Expand Down

0 comments on commit d991016

Please sign in to comment.