Files
fn_registry/dev/issues/0036-cpp-image-canvas-webcam.md
T
egutierrez a11a58dab0 docs(issues): añadir 0025-0036 — features C++ para registry y primitives_gallery
12 issues nuevos para implementacion paralela: text_editor, file_watcher,
gl_texture_load, gl_compute+pingpong+DAG Compute, ImPlot3D, mesh_viewer,
audio reactivo, animation curves, sql_workbench, http+ws inspector,
scientific viz (5 charts), map_tiles, image_canvas + webcam_texture.

Cada issue añade funciones al registry y un demo propio en
primitives_gallery/demos_<feature>.cpp para minimizar conflictos en paralelo.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 20:48:18 +02:00

5.1 KiB
Raw Blame History

0036 — C++ image_canvas + webcam_texture

APP Metadata

Campo Valor
ID 0036
Estado pendiente
Prioridad baja
Tipo feature — C++ core/gfx (cpp/functions/core, cpp/functions/gfx)

Dependencias

gl_texture_load_cpp_gfx (issue 0026) — recomendado. tokens_cpp_core. Independiente de los demas.

Desbloquea: UIs para etiquetado/anotacion de imagenes (CV, OCR debugging) y entrada de webcam para shaders_lab reactivo a video.


Objetivo

Dos primitivos:

  1. image_canvas_cpp_core — viewer de imagen con pan/zoom + capa de anotaciones (rectangulos, puntos, polilineas, texto). Drag para crear nuevas anotaciones; click para seleccionar; tecla Del para borrar.
  2. webcam_texture_cpp_gfx — captura de webcam (V4L2 en Linux, Media Foundation en Windows) → GL texture actualizada cada frame. API parejo a audio_capture.

Contexto

Casos de uso identificados:

  • Inspeccionar resultados de un detector (rectangulos overlay).
  • Etiquetar manualmente datasets pequeños in-app.
  • Pasar webcam a shaders en shaders_lab (filtros video en tiempo real).

Ningun primitivo del registry actual cubre estos casos.

Arquitectura

cpp/functions/core/
├── image_canvas.h               # NEW
├── image_canvas.cpp             # NEW
└── image_canvas.md              # NEW (impure component)
cpp/functions/gfx/
├── webcam_texture.h             # NEW
├── webcam_texture.cpp           # NEW
└── webcam_texture.md            # NEW (impure)
cpp/apps/primitives_gallery/
├── demos_image_webcam.cpp       # NEW
├── demos.h                      # MOD
├── main.cpp                     # MOD
└── CMakeLists.txt               # MOD

API propuesta

namespace fn {

// --- image_canvas ---
struct Annotation {
    enum Kind { Rect, Point, Polyline, Text } kind;
    std::vector<ImVec2> points;   // image-space coords (no screen)
    ImU32       color = IM_COL32(255, 80, 80, 255);
    std::string label;
};
struct ImageCanvasState {
    GLuint texture = 0;           // caller-owned
    int    img_w = 0, img_h = 0;
    float  zoom  = 1.f;
    ImVec2 pan   = {0, 0};
    std::vector<Annotation> annotations;
    int    selected = -1;
    enum   Tool { ToolNone, ToolRect, ToolPoint, ToolPolyline } tool = ToolNone;
};
void image_canvas(const char* id, ImageCanvasState&, ImVec2 size = {-1, -1});

// --- webcam_texture ---
struct WebcamTextureConfig { int width = 640; int height = 480; int fps = 30; int device = 0; };
struct WebcamTexture { GLuint id = 0; int w = 0; int h = 0; bool ok() const { return id != 0; } };
WebcamTexture webcam_texture_start(const WebcamTextureConfig&);
void          webcam_texture_stop(WebcamTexture&);
bool          webcam_texture_update(WebcamTexture&);  // copia ultimo frame a GPU; true si hubo nuevo
const char*   webcam_texture_last_error();
}

Tareas

Fase 1 — image_canvas

  • 1.1 Render: ImGui::Image(texture, ...) con transform por pan/zoom. Drag con MMB para pan, wheel para zoom.
  • 1.2 Tool == Rect: drag con LMB en image-space crea anotacion Rect con 2 puntos.
  • 1.3 Tool == Point: click LMB anade un Point.
  • 1.4 Tool == Polyline: click anade puntos; doble-click cierra.
  • 1.5 Hit-test para selection; Del key elimina la seleccionada.
  • 1.6 .md.

Fase 2 — webcam_texture (Linux V4L2)

  • 2.1 Abrir /dev/video<device>, MMAP buffers, VIDIOC_STREAMON.
  • 2.2 En update, dequeue buffer, convert YUYV → RGBA (CPU), upload a GL texture, requeue.
  • 2.3 .md (kind: function, purity: impure, error_type).

Fase 3 — webcam_texture (Windows Media Foundation, opcional)

  • 3.1 Si _WIN32, usar IMFSourceReader. Convert NV12 → RGBA.
  • 3.2 Documentar que macOS no se soporta en MVP.
  • 4.1 demos_image_webcam.cpp:
    • demo_image_canvas(): carga assets/sample.png (si existe — fallback a rendered placeholder), permite pintar rectangulos.
    • demo_webcam_texture(): start cam, mostrar preview + sliders RGB sobre un shader fullscreen que samplea la cam.
  • 4.2 Registrar.

Fase 5 — Tests + docs

  • 5.1 Tests puros de transform image-space ↔ screen-space.
  • 5.2 Smoke test webcam (skip si no hay /dev/video0).
  • 5.3 ./fn index.

Ejemplo de uso

auto cam = fn::webcam_texture_start({});
if (!cam.ok()) std::fprintf(stderr, "%s\n", fn::webcam_texture_last_error());

fn::run_app("cam", [&]{
    fn::webcam_texture_update(cam);
    ImGui::Image((ImTextureID)(intptr_t)cam.id, {cam.w*1.f, cam.h*1.f});
});

Decisiones de diseño

  • Anotaciones en image-space: pan/zoom no afectan coordenadas guardadas. Permite serializar a JSON (issue futuro).
  • YUYV → RGBA en CPU: simple, ~5ms/frame a 640×480. Si hace falta, hacer un compute shader (issue 0027).
  • macOS sin webcam por ahora: AVFoundation requiere ObjC++; no compensa en MVP.

Riesgos

  • Permisos webcam: documentar troubleshooting (/dev/video0 permisos en Linux).
  • Driver V4L2 raro: algunos formatos de pixel no son YUYV. Documentar fallback a MJPEG (con stb_image decode) o error claro.
  • ImTextureID semantics entre backends: documentar.