Analyze Arousal Valence with MorphCast SDK v1.16

by morphcast

HTML

<input type="file" id="photo" accept="image/*">
<button id="analyze">Analyze Arousal/Valence</button>
<pre id="out"></pre>

<script src="https://ai-sdk.morphcast.com/v1.16/ai-sdk.js"></script>
<script>
  // ---------- Helpers ----------
  const outEl = document.getElementById('out');
  const print = (obj) => outEl.textContent = typeof obj === 'string'
    ? obj
    : JSON.stringify(obj, null, 2);

  // Convert File -> ImageData (draw once on an offscreen canvas)
  async function fileToImageData(file) {
    const url = URL.createObjectURL(file);
    try {
      const img = new Image(); img.crossOrigin = 'anonymous';
      await new Promise((ok, ko) => { img.onload = ok; img.onerror = ko; img.src = url; });
      const c = document.createElement('canvas');
      const ctx = c.getContext('2d', { willReadFrequently: true });
      c.width = img.naturalWidth; c.height = img.naturalHeight;
      ctx.drawImage(img, 0, 0);
      return ctx.getImageData(0, 0, c.width, c.height);
    } finally { URL.revokeObjectURL(url); }
  }

  // ---------- Custom single-frame source ----------
  // Produces exactly one ImageData on demand via analyzeFrame(...)
  let pending = null, resolver = null;
  const photoSource = {
    // Called by your app to push the next frame
    analyzeFrame(imageData) {
      if (resolver) { resolver(imageData); resolver = null; }
      else { pending = imageData; }
    },
    // Called by the SDK to fetch a frame
    getFrame() {
      if (pending) { const p = Promise.resolve(pending); pending = null; return p; }
      return new Promise(res => resolver = res);
    },
    start(){}, stop(){}, get stopped(){ return false; }
  };

  // ---------- SDK init (one-time) ----------
  let startSdk, stopSdk, sdkReady = false;

  (async () => {
    const { start, stop } = await CY.loader()
      .licenseKey("9087cfd2037a28a79769fdcaa4962252379cd2e2fd0b")                   // required if your license demands it
     ...