Il ridimensionamento può essere eseguito in vari modi, ma tutti si riducono alla rimozione o alla creazione di pixel dall'immagine. Poiché le immagini sono essenzialmente matrici (ridimensionate come matrici) di valori di pixel, è possibile osservare il ridimensionamento delle immagini come ingrandendo quella matrice e riempendo gli spazi vuoti e ridimensionando le immagini riducendo la matrice lasciando i valori fuori.
Detto questo, in genere non è così difficile scrivere la propria funzione di scala in JavaScript che funziona sugli array. Poiché capisco che hai già le immagini sotto forma di un array JavaScript, puoi passare quell'array in un messaggio al Web Worker, ridimensionarlo come funzione di scala e rimandare l'array ridimensionato al thread principale.
In termini di rappresentazione, consiglierei di utilizzare Uint8ClampedArray che è stato progettato per le immagini codificate RGBA (a colori, con canale alfa) ed è più efficiente dei normali array di JavaScript. È inoltre possibile inviare facilmente oggetti Uint8ClampedArray nei messaggi al proprio Web Worker, in modo da non costituire un problema. Un altro vantaggio è che Uint8ClampedArray viene utilizzato nel tipo di dati ImageData (dopo la sostituzione di CanvasPixelArray) dell'API Canvas. Ciò significa che è abbastanza semplice riportare l'immagine ridimensionata su una tela (se questo era ciò che volevi), semplicemente ottenendo gli attuali ImageData del contesto 2D della tela usando ctx.getImageData() e modificando l'attributo dei dati in scala Oggetto Uint8ClampedArray.
A proposito, se non hai ancora le tue immagini come matrici puoi usare lo stesso metodo. Per prima cosa disegna l'immagine sulla tela e poi usa l'attributo data dell'oggetto ImageData corrente per recuperare l'immagine in un Uint8ClampedArray.
Per quanto riguarda i metodi di ridimensionamento per l'ingrandimento di un'immagine, sono essenzialmente due i componenti che è necessario implementare. Il primo è quello di dividere i pixel conosciuti (cioè i pixel dell'immagine che si sta ridimensionando) sul nuovo array più grande che si è creato. Un modo ovvio è di dividere equamente tutti i pixel nello spazio. Ad esempio, se si sta rendendo la larghezza di un'immagine due volte più ampia, si desidera semplicemente saltare una posizione dopo ogni pixel lasciando spazi vuoti in mezzo.
Il secondo componente deve quindi riempire quegli spazi vuoti, che possono essere leggermente meno diretti. Tuttavia, ci sono molti che sono abbastanza facili. (D'altra parte, se hai una certa conoscenza di Computer Vision o Elaborazione delle immagini potresti voler esaminare alcuni metodi più avanzati.) Un metodo facile e in qualche modo ovvio è quello di interpolare ogni posizione di pixel sconosciuti usando il suo vicino più vicino (cioè il più vicino valore del pixel noto) duplicando il colore del pixel noto. Questo in genere comporta l'effetto di pixel più grandi (blocchi più grandi dello stesso colore) quando si ridimensionano eccessivamente le immagini. Invece di duplicare il colore del pixel più vicino, puoi anche prendere la media di diversi pixel noti che si trovano nelle vicinanze. Forse anche combinato con pesi, hai reso i pixel più vicini contano più nella media rispetto ai pixel che sono più lontani. Altri metodi includono la sfocatura dell'immagine usando gaussiani. Se vuoi scoprire quale metodo è il migliore per la tua applicazione, guarda alcune pagine sull'interpolazione delle immagini. Certo, ricorda che scalare significa sempre riempire cose che non sono realmente lì. Che sarà sempre male se lo fai troppo.
Per quanto riguarda il ridimensionamento, in genere si rimuovono solo i pixel trasferendo solo una selezione di pixel dall'array corrente all'array più piccolo.Ad esempio, se si desidera ottenere un'immagine con una dimensione doppia più piccola, si esegue una ripetizione approssimativa della matrice corrente con passaggi di 2 (Ciò dipende un po 'dalle dimensioni dell'immagine, pari o dispari, e dalla rappresentazione che si è usando). Ci sono metodi che lo fanno ancora meglio rimuovendo quei pixel che potrebbero essere persi di più. Ma non ne so abbastanza di loro.
A proposito, tutto ciò è praticamente estraneo ai web worker. Lo farebbe esattamente nello stesso modo se si desidera ridimensionare le immagini in JavaScript sul thread principale. O in qualsiasi altra lingua per quella materia. I Web Worker sono comunque un modo molto carino per eseguire questi calcoli su un thread separato anziché sul thread dell'interfaccia utente, il che significa che il sito Web stesso non sembra non rispondere. Tuttavia, come hai detto tu, tutto ciò che riguarda l'elemento canvas deve essere fatto sul thread principale, ma gli array di ridimensionamento possono essere fatti ovunque.
Inoltre, sono sicuro che ci sono librerie JavaScript che possono fare questo per te e, in base ai loro metodi, puoi anche caricarle nel tuo Web Worker usando importScripts. Ma direi che in questo caso potrebbe essere più facile e molto più divertente provare a scrivere da solo e renderlo su misura per il tuo scopo.
E a seconda di quanto avanzate sono le tue capacità di programmazione e la velocità alla quale devi ridimensionare, puoi sempre provare a farlo sulla GPU anziché sulla CPU usando WebGL. Ma questo sembra un po 'eccessivo in questo caso. Inoltre, puoi provare a tagliare la tua immagine in più parti e provare a scalare le parti separate su diversi Web Worker rendendola multi-threaded. Anche se non è certamente banale combinare le parti in seguito. Forse il multi-thread ha più senso quando si hanno molte immagini che devono essere ridimensionate sul lato client.
Tutto dipende davvero dalla vostra applicazione, dalle immagini e dalle vostre capacità e desideri.
In ogni caso, spero che risponda grosso modo alla tua domanda.
Hey man Ho bisogno di fare lo stesso, hai findf qualsiasi ImageData/ByteArray RGBA sovrappone e ridimensiona le librerie o le funzioni su/giù? – Noitidart