Zum Inhalt springen

MediaWiki:Gadget-LabelScan.js: Unterschied zwischen den Versionen

Aus ADOS Wiki
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 152: Zeile 152:
   } else {
   } else {
     bind();
     bind();
// ----- Helpers: Status/Preview/Datei -----
let _pickedFile = null;
function setStatus(t){ const el=document.getElementById('ados-scan-status'); if(el) el.textContent=t||''; }
function showPreview(file){
  const prev=document.getElementById('ados-scan-preview');
  if(!prev) return;
  const url=URL.createObjectURL(file);
  prev.innerHTML = `<img src="${url}" alt="Vorschau" style="max-width:100%; border-radius:6px;">`;
  setStatus('Bild bereit.');
}
function getSelectedFile(){
  const c=document.getElementById('ados-scan-file-camera');
  const g=document.getElementById('ados-scan-file-gallery');
  return _pickedFile || (c && c.files && c.files[0]) || (g && g.files && g.files[0]) || null;
}
// ----- Buttons sauber binden -----
(function wirePickers(){
  const btnCam = document.getElementById('ados-scan-btn-camera');
  const btnGal = document.getElementById('ados-scan-btn-gallery');
  const inCam  = document.getElementById('ados-scan-file-camera');
  const inGal  = document.getElementById('ados-scan-file-gallery');
  if (btnCam && inCam) {
    btnCam.addEventListener('click', function(ev){
      ev.preventDefault(); ev.stopPropagation();
      inCam.click();
    });
    inCam.addEventListener('change', function(){
      if (inCam.files && inCam.files[0]) {
        _pickedFile = inCam.files[0];
        showPreview(_pickedFile);
      }
    });
  }
  if (btnGal && inGal) {
    btnGal.addEventListener('click', function(ev){
      ev.preventDefault(); ev.stopPropagation();
      inGal.click();
    });
    inGal.addEventListener('change', function(){
      if (inGal.files && inGal.files[0]) {
        _pickedFile = inGal.files[0];
        showPreview(_pickedFile);
      }
    });
  }
})();
// ----- Drag&Drop auf der Dropzone -----
(function wireDropzone(){
  const drop = document.getElementById('ados-scan-drop');
  if (!drop) return;
  const stop = e => { e.preventDefault(); e.stopPropagation(); };
  ['dragenter','dragover','dragleave','drop'].forEach(evt => drop.addEventListener(evt, stop));
  drop.addEventListener('drop', e => {
    const f = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];
    if (f) { _pickedFile = f; showPreview(f); }
  });
})();
// ----- „Erkennen & suchen“ nutzt immer die aktuell gewählte Datei -----
(function wireRun(){
  const runBtn = document.getElementById('ados-scan-run');
  if (!runBtn) return;
  runBtn.addEventListener('click', async function(ev){
    ev.preventDefault();
    const file = getSelectedFile();
    if (!file) { alert('Bitte Foto aufnehmen oder Datei wählen.'); return; }
    // HIER: dein bestehender Erkennungs-Workflow (phash / Vergleich)
    // Beispiel:
    // setStatus('Berechne Fingerabdruck …'); const img = await fileToImage(file);
    // const hash = computePhash(img); … vergleichen … renderResults(…)
  });
})();
   }
   }
})();
})();

Version vom 7. November 2025, 22:39 Uhr

// Kamera öffnen
document.getElementById('ados-scan-btn-camera')?.addEventListener('click', () => {
  document.getElementById('ados-scan-file-camera').click();
});

// Galerie öffnen
document.getElementById('ados-scan-btn-gallery')?.addEventListener('click', () => {
  document.getElementById('ados-scan-file-gallery').click();
});

// Vorschau für beide Inputs
['ados-scan-file-camera','ados-scan-file-gallery'].forEach(id => {
  const el = document.getElementById(id);
  if (!el) return;
  el.addEventListener('change', () => {
    if (el.files && el.files[0]) {
      const url = URL.createObjectURL(el.files[0]);
      document.getElementById('ados-scan-preview').innerHTML = `<img src="${url}" style="max-width:100%; border-radius:6px;">`;
      document.getElementById('ados-scan-status').textContent = 'Bild bereit.';
    }
  });
});








/* global mw */
(function () {
  'use strict';

  // === Hilfsfunktionen =====================================================
  async function fileToImage (file) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = reject;
      img.src = URL.createObjectURL(file);
    });
  }

  function getCanvas (img, size = 32) {
    const c = document.createElement('canvas');
    c.width = c.height = size;
    const ctx = c.getContext('2d');
    ctx.drawImage(img, 0, 0, size, size);
    return ctx.getImageData(0, 0, size, size).data;
  }

  function computePhash (img) {
    const size = 32;
    const pixels = getCanvas(img, size);
    const gray = [];
    for (let i = 0; i < pixels.length; i += 4) {
      gray.push(0.299 * pixels[i] + 0.587 * pixels[i + 1] + 0.114 * pixels[i + 2]);
    }
    const avg = gray.reduce((a, b) => a + b, 0) / gray.length;
    const bits = gray.map(v => (v > avg ? 1 : 0));
    let hash = '';
    for (let i = 0; i < bits.length; i += 4) {
      const nibble = bits.slice(i, i + 4).reduce((a, b, j) => a | (b << (3 - j)), 0);
      hash += nibble.toString(16);
    }
    return hash;
  }

  function hamming (h1, h2) {
    let d = 0;
    const len = Math.min(h1.length, h2.length);
    for (let i = 0; i < len; i++) {
      const x = parseInt(h1[i], 16) ^ parseInt(h2[i], 16);
      d += x.toString(2).replace(/0/g, '').length;
    }
    return d;
  }

  async function loadIndex () {
    const url = mw.util.getUrl('MediaWiki:Gadget-LabelScan-index.json', { action: 'raw', ctype: 'application/json' });
    const res = await fetch(url);
    return res.json();
  }

  // === UI-Helfer ===========================================================
  function showPreview (file) {
    const prev = document.getElementById('ados-scan-preview');
    if (prev) prev.innerHTML = `<img alt="Vorschau" src="${URL.createObjectURL(file)}">`;
  }
  function setStatus (t) {
    const el = document.getElementById('ados-scan-status');
    if (el) el.textContent = t;
  }
  function renderResults (hits) {
    const box = document.getElementById('ados-scan-results');
    box.innerHTML = '';
    if (!hits.length) {
      box.innerHTML = '<div>Keine klaren Treffer gefunden.</div>';
      return;
    }
    hits.forEach(h => {
      box.innerHTML += `
        <div class="ados-hit">
          <a href="${mw.util.getUrl(h.title)}">
            <img src="${h.thumb}" alt="${h.title}">
            <br><b>${mw.html.escape(h.title)}</b>
          </a>
          <small>Distanz: ${h.dist}</small>
        </div>`;
    });
  }

  // === Haupt-Bindung =======================================================
  async function bind () {
    const runBtn = document.getElementById('ados-scan-run');
    const fileIn = document.getElementById('ados-scan-file');
    const bigBtn = document.getElementById('ados-scan-bigbtn');
    if (!runBtn || !fileIn) return;

    bigBtn?.addEventListener('click', () => fileIn.click());
    fileIn.addEventListener('change', e => { if (e.target.files[0]) showPreview(e.target.files[0]); });

    runBtn.addEventListener('click', async ev => {
      ev.preventDefault();
      const file = fileIn.files[0];
      if (!file) return alert('Bitte ein Bild wählen.');
      try {
        setStatus('Berechne Hash …');
        const img = await fileToImage(file);
        const ph = computePhash(img);

        setStatus('Lade Index …');
        const idx = await loadIndex();

        setStatus('Vergleiche …');
        const scored = idx.map(it => ({ ...it, dist: hamming(ph, it.phash) }));
        scored.sort((a, b) => a.dist - b.dist);

        const top = scored.slice(0, 5);
        renderResults(top);
        setStatus('Fertig.');
      } catch (e) {
        console.error('[LabelScan]', e);
        setStatus('Fehler bei Erkennung.');
      }
    });
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', bind);
  } else {
    bind();
// ----- Helpers: Status/Preview/Datei -----
let _pickedFile = null;

function setStatus(t){ const el=document.getElementById('ados-scan-status'); if(el) el.textContent=t||''; }
function showPreview(file){
  const prev=document.getElementById('ados-scan-preview');
  if(!prev) return;
  const url=URL.createObjectURL(file);
  prev.innerHTML = `<img src="${url}" alt="Vorschau" style="max-width:100%; border-radius:6px;">`;
  setStatus('Bild bereit.');
}
function getSelectedFile(){
  const c=document.getElementById('ados-scan-file-camera');
  const g=document.getElementById('ados-scan-file-gallery');
  return _pickedFile || (c && c.files && c.files[0]) || (g && g.files && g.files[0]) || null;
}

// ----- Buttons sauber binden -----
(function wirePickers(){
  const btnCam = document.getElementById('ados-scan-btn-camera');
  const btnGal = document.getElementById('ados-scan-btn-gallery');
  const inCam  = document.getElementById('ados-scan-file-camera');
  const inGal  = document.getElementById('ados-scan-file-gallery');

  if (btnCam && inCam) {
    btnCam.addEventListener('click', function(ev){
      ev.preventDefault(); ev.stopPropagation();
      inCam.click();
    });
    inCam.addEventListener('change', function(){
      if (inCam.files && inCam.files[0]) {
        _pickedFile = inCam.files[0];
        showPreview(_pickedFile);
      }
    });
  }
  if (btnGal && inGal) {
    btnGal.addEventListener('click', function(ev){
      ev.preventDefault(); ev.stopPropagation();
      inGal.click();
    });
    inGal.addEventListener('change', function(){
      if (inGal.files && inGal.files[0]) {
        _pickedFile = inGal.files[0];
        showPreview(_pickedFile);
      }
    });
  }
})();

// ----- Drag&Drop auf der Dropzone -----
(function wireDropzone(){
  const drop = document.getElementById('ados-scan-drop');
  if (!drop) return;
  const stop = e => { e.preventDefault(); e.stopPropagation(); };
  ['dragenter','dragover','dragleave','drop'].forEach(evt => drop.addEventListener(evt, stop));
  drop.addEventListener('drop', e => {
    const f = e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files[0];
    if (f) { _pickedFile = f; showPreview(f); }
  });
})();

// ----- „Erkennen & suchen“ nutzt immer die aktuell gewählte Datei -----
(function wireRun(){
  const runBtn = document.getElementById('ados-scan-run');
  if (!runBtn) return;
  runBtn.addEventListener('click', async function(ev){
    ev.preventDefault();
    const file = getSelectedFile();
    if (!file) { alert('Bitte Foto aufnehmen oder Datei wählen.'); return; }

    // HIER: dein bestehender Erkennungs-Workflow (phash / Vergleich)
    // Beispiel:
    // setStatus('Berechne Fingerabdruck …'); const img = await fileToImage(file);
    // const hash = computePhash(img); … vergleichen … renderResults(…)
  });
})();





  }
})();