Come rappresentare la profondità del colore a 18 bit a 16 bit di profondità di colore?

Sto eseguendo il porting di un software che costruisce da una profondità di colore di 16 bit a una profondità di colore di 18 bit. Come posso convertire i colors a 16 bit in colors a 18 bit? Grazie.

Senza conoscere il dispositivo, posso solo speculare. I dispositivi sono in genere rosso, verde, blu, quindi ogni colore otterrebbe 6 bit di variazione. Ciò significa 64 variazioni di ogni colore e un totale di 262.144 colors.

Qualsiasi bitmap può essere ridimensionato a questo display. Se prendi ciascun componente (ad esempio, rosso), normalizzalo, quindi moltiplica per 64, avrai la versione ridimensionata.

Se stai chiedendo qualcos’altro o vuoi maggiori dettagli, per favore chiedi.

Aggiornare:
Esistono due formati bitmap a 16 bit. Uno è 5-5-5 (5 bit per pixel) e l’altro è 5-6-5 (il verde ottiene un bit in più). Assumerò 5-5-5 per amore di questa conversione.

Per ogni colore all’interno di ciascun pixel hai bisogno di qualcosa del genere:

NewColor = (oldColor/32.0)*64 

Questo trasformsrà il vecchio colore in un numero compreso tra 0.0 e 1.0 e lo ridimensionerà fino al nuovo intervallo di valori.

Supponendo che il colore a 16 bit sia nel formato 5-6-5:

 // RRRRR-GGGGGG-BBBBB, 16bit --> //RRRRR0-GGGGGG-BBBBB0, 18bit with the formula below: Color18 = ((Color16 & 0xF800) << 2) | ((Color16 & 0x07E0) << 1) | ((Color16 & 0x1F) << 1); 

Non vedo questo trattato nelle altre risposte, ma tu vuoi che la conversione da 5 a 6 bit sia tale che 11111 binario venga mappato a 111111, poiché entrambi rappresentano il pieno . Un modo per farlo è replicare il / i bit / i principale / i.

 red6 = (red5 << 1) | (red5 >> 4); 

Se si utilizza una conversione aritmetica, tenere presente che i valori massimi sono 31 e 63, non 32 e 64.

 red6 = (red5 * 63 + 15) / 31; // all ints, +15 is for rounding 

Se ti interessano altri valori intermedi, ad esempio se vuoi 16 mappato 32, modifica la formula (ad es. Cambia da 15 a 14) o crea semplicemente una tabella.

Per rispondere alla domanda di conversione

Non ho familiarità con le librerie di immagini c ++ ma sono sicuro che questo codice esiste già da qualche parte. Ma se vuoi puoi farlo da solo.

Ogni pixel ha tre canali: rosso, verde e blu. In una bitmap a 16 bit, ogni canale non ha lo stesso numero di bit per canale. In genere, il verde è il primo ad ottenere bit in più perché l’occhio umano è più sensibile a quel colore.

Probabilmente è 565 – 5 per il rosso, 6 per il verde e 5 per il blu.

Per una bitmap a 18 bit (come precedentemente affermato), ogni canale ha 6 bit. Quindi il verde è facile! Basta copiare il valore dal formato a 16 bit al formato a 18 bit. Gli altri due canali sono leggermente più difficili. Devi interpolare da 5 a 6:

 18_Value = (16_Value / 32) * 64 //integers only of course. You need to round properly to get best results. 

E il gioco è fatto. Se non hai già familiarità con quanto segue, ti suggerisco di cercarli:

  • Operatori di spostamento di bit
  • Bitmap Stride
  • Pointer Math
  • Allineamento dei byte

– Modifica … Assicurati di sapere come sono disposte le cose nella memoria; RGB o BGR. Ti rovinerà la testa se farai qualcosa di più complicato di questo e ci stai pensando all’indietro (dato che Green è nel mezzo non è così importante per questa conversione).

Per prima cosa dovrete accedere a ciascuna delle componenti del colore (ad esempio, estrarre il valore R, il valore G e il valore B). Il modo per farlo dipenderà totalmente dal modo in cui il colore è memorizzato nella memoria. Se è memorizzato come RGB, con 5-6-5 bit per i componenti, è ansible utilizzare qualcosa come questo:

 blueComponent = (colour & 0x1F); greenComponent = (colour >> 5 ) & 0x3F; redComponent = (colour >> 11) & 0x1F; 

Questo estrae i componenti del colore per te, quindi puoi utilizzare il metodo descritto sopra per convertire ciascuno dei componenti (presumo che 18 bit utilizzi 6 bit per componente):

 blueComponent = (blueComponent / 32.0) * 64; //greenComponent = (greenComponent / 64.0) * 64; // not needed redComponent = (redComponent / 32.0) * 64; 

Nota che con il codice sopra, è importante usare 32.0 , o qualche altro metodo che assicuri che il tuo programma rappresenti il ​​numero come un numero in virgola mobile. Quindi per unire i componenti nel tuo colore a 18 bit, usa:

 colour = (redComponent << 12) | (greenComponent << 6) | blueComponent;