Encapsulate bitmap (* .bmp) come classe C ++

3

Come implementereste / progettate una classe che deve rappresentare una bitmap? Sono bloccato a gestire le diverse modalità di colore possibili e continuo a pensare che questo dovrebbe essere in qualche modo implementabile usando modelli / schemi di progettazione in un modo elegante ed efficiente:

Supponiamo di avere un file.bmp. Quindi vuoi aprire quel file per usarlo nella tua applicazione:

Bitmap myBitmap();
myBitmap.open("file.bmp");

La bitmap che hai appena aperto potrebbe avere i colori RGB, oppure potrebbe essere un'immagine in scala di grigi o anche un'immagine da 1 bit per pixel (cioè bianco e nero). Nella mia applicazione, voglio operare sui dati dell'immagine (pixel). Ad esempio, ho bisogno di una sorta di filtro di luminosità in cui oscuro i pixel di cui (Rosso + Blu + Verde) / 3 è al di sotto di qualche valore di filtro (cioè 100).

Quindi ho bisogno di accedere ai pixel:

Pixel somePixel = myBitmap.pixelAt(10,30);

Ma ora affronto il problema di NON sapere che tipo di pixel sia. Naturalmente, potrei fornire sottoclassi di Pixel (che quindi è una classe base astratta) che TUTTA implementa metodi come getRGB() , getGrayScale() , ... dove ogni sottoclasse dà un modo di convertire tra quei colormodes (cioè RGB in scala di grigi)

Ma questo sembra ... hm, "sbagliato".

Conosci qualche buon metodo per implementarlo?

Una bella funzionalità a cui stavo pensando è qualcosa del tipo:

myBitmap.getMode(); // A RGBMode object, RGBMode being a subclass of Mode
myBitmap.setMode(new BlackWhiteMode()); // Converts the bitmap to a 1bpp image

Qualche idea, consigli, miglioramenti?

Quindi la parte più difficile è rappresentare le diverse modalità di colore, come RGB (8 bit e 4 bit), HSV, scala di grigi, nero bianco, ... senza compromettere il codice dell'applicazione.

    
posta Daniel Jour 21.12.2012 - 00:14
fonte

1 risposta

3

A seconda delle esigenze di elaborazione, sceglierei:

a) Una classe bitmap che memorizza i dati grezzi dei pixel e le informazioni sul formato; durante il caricamento, risolvi la compressione RLE, ma altrimenti lascia intatti i valori di pixel non elaborati. Quindi aggiungi alcuni metodi per interrogare la classe per il suo formato pixel, e possibilmente una coppia getter / setter per modificare in modo trasparente i pixel in un formato indipendente dal formato (cioè, convertire da e verso la rappresentazione RGB in virgola mobile al volo). Se è necessario convertire tra formati di pixel, lo si farebbe in questo modello caricando la bitmap originale, creando una nuova bitmap vuota con il formato di destinazione desiderato e quindi copiando i pixel attraverso i getter / setter RGB in virgola mobile. b) Memorizza i dati dei pixel come float RGB (o interi a 16 bit, a seconda del tipo di trasformazioni che vuoi fare). Durante il caricamento, converti tutto in quel formato e, al momento del salvataggio, specifica esplicitamente il formato del pixel di destinazione.

Il metodo a) ha il vantaggio che alcuni filtri possono essere implementati in un modo completamente privo di perdite, utilizzando dati grezzi e adattando il filtro al formato di pixel effettivo; è più complicato scrivere tali filtri, e se si applicano più di un filtro a virgola mobile, si otterranno più errori di arrotondamento su ogni passaggio (perché si converte ogni volta da e verso l'intero).

Il metodo b) è più facile da implementare, soprattutto perché i filtri hanno sempre bisogno di un solo formato pixel e produce meno errori di arrotondamento, ma non consente filtri completamente senza perdita di dati (nemmeno un filtro di identità: caricamento e poi il salvataggio della stessa bitmap introduce ancora un errore di conversione da intero a virgola mobile di un round trip).

    
risposta data 21.12.2012 - 09:59
fonte

Leggi altre domande sui tag