Changeset - 9bb0eb587d5b
[Not reviewed]
default
0 1 0
drewp@bigasterisk.com - 8 months ago 2024-05-21 18:58:13
drewp@bigasterisk.com
640x480 camera res
1 file changed with 2 insertions and 0 deletions:
0 comments (0 inline, 0 general)
web/calibrate/Light9Camera.ts
Show inline comments
 
@@ -31,96 +31,98 @@ export class Light9Camera extends LitEle
 
      }
 
      @keyframes fadeIn {
 
        from {
 
          opacity: 0;
 
        }
 
        to {
 
          opacity: 1;
 
        }
 
      }
 
    `,
 
  ];
 
  videoEl!: HTMLVideoElement;
 
  canvas!: HTMLCanvasElement;
 
  ctx!: CanvasRenderingContext2D;
 
  @state()
 
  vtrack: MediaStreamTrack | undefined;
 

	
 
  @property() saturatedPixelCount = 0;
 
  @property() saturatedPixelFraction = 0;
 

	
 
  @property() videoSettings: MediaTrackSettings & any = {};
 

	
 
  render() {
 
    const saturatedCountDisplay = `${this.saturatedPixelCount} (${(this.saturatedPixelFraction * 100).toFixed(2)}%)`;
 

	
 
    return html`
 
      <video id="video"></video>
 

	
 
      <div id="stack">
 
        <img src="zebra.png" />
 
        <canvas id="canvas"></canvas>
 
      </div>
 
      <div id="controls">
 
        <p>saturated pixels: ${saturatedCountDisplay}</p>
 
        <light9-camera-settings-table .cam=${this} .videoSettings=${this.videoSettings}></light9-camera-settings-table>
 
      </div>
 
    `;
 
  }
 

	
 
  protected async firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
 
    this.videoEl = this.shadowRoot!.getElementById("video") as HTMLVideoElement;
 
    this.canvas = this.shadowRoot!.getElementById("canvas") as HTMLCanvasElement;
 
    this.ctx = this.canvas.getContext("2d", { willReadFrequently: true })!;
 

	
 
    const constraints: MediaStreamConstraints = {
 
      video: {
 
        facingMode: { ideal: "environment" },
 
        frameRate: { max: 10 },
 
        width: 640,
 
        height: 480,
 
      },
 
    };
 
    const stream = await navigator.mediaDevices.getUserMedia(constraints);
 
    const t = stream.getVideoTracks()[0];
 
    await t.applyConstraints({
 
      brightness: 0,
 
      contrast: 32,
 
      colorTemperature: 6600,
 
      exposureMode: "manual",
 
      exposureTime: 250,
 
      whiteBalanceMode: "manual",
 
      focusMode: "manual",
 
      focusDistance: 235,
 
    } as MediaTrackConstraints);
 

	
 
    this.vtrack = t;
 
    this.videoEl.srcObject = stream;
 
    this.videoEl.play();
 
    this.videoSettings = this.vtrack.getSettings();
 

	
 
    this.redrawLoop();
 
  }
 

	
 
  redrawLoop() {
 
    if (this.videoEl.videoWidth !== 0 && this.videoEl.videoHeight !== 0) {
 
      this.redraw();
 
    }
 
    // todo: video frames come slower than raf is waiting
 
    requestAnimationFrame(this.redrawLoop.bind(this));
 
  }
 

	
 
  public async set(k: string, v: any) {
 
    if (!this.vtrack) {
 
      throw new Error("vtrack");
 
    }
 
    await this.vtrack.applyConstraints({ [k]: v });
 
    this.videoSettings = this.vtrack.getSettings();
 
  }
 

	
 
  private redraw() {
 
    this.canvas.width = this.videoEl.videoWidth;
 
    this.canvas.height = this.videoEl.videoHeight;
 
    this.ctx.drawImage(this.videoEl, 0, 0);
 
    this.makeSaturatedPixelsTransparent();
 
  }
 

	
 
  private makeSaturatedPixelsTransparent() {
 
    const imageData = this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
0 comments (0 inline, 0 general)