Domanda

Ho un array di byte che rappresentano un'immagine in formato di Windows BMP e vorrei che la mia libreria per presentarlo al l'applicazione Java come BufferedImage, senza la copia dei dati dei pixel.

Il problema principale è che tutte le implementazioni di Raster nel JDK pixel dell'immagine negozio in top-down, ordine da sinistra a destra, mentre i dati di pixel vengono memorizzati BMP bottom-up, da sinistra a destra. Se questo non viene compensata, l'immagine risultante sarà girato in verticale.

La "soluzione" più ovvia è impostare la proprietà SampleModel del scanlineStride ad un valore negativo e modificare gli offset di banda (o matrice del DataBuffer offset) per puntare il pixel in alto a sinistra, cioè il primo pixel dell'ultima riga la matrice. Purtroppo questo non funziona perché tutti i costruttori SampleModel gettare un'eccezione se dato un argomento scanlineStride negativo.

Al momento sto lavorando intorno ad esso forzando il campo scanlineStride ad un valore negativo utilizzando la riflessione, ma mi piacerebbe farlo in un modo più pulito e più portabile, se possibile. per esempio. c'è un altro modo per ingannare il Raster o SampleModel nel disporre i pixel in modo bottom-up, ma senza rompere l'incapsulamento? O c'è un qualche libreria che vi avvolgerà il Raster e SampleModel, presentando le righe di pixel in ordine inverso?

Io preferirei evitare i seguenti approcci:

  • copia l'intera immagine (per motivi di prestazioni. Il codice deve elaborare centinaia di grandi dimensioni (> = 1Mpixels) immagini al secondo e, sebbene l'intera immagine deve essere disponibile per l'applicazione, normalmente accedere solo una piccola (ma hardware da prevedere) parte dell'immagine.)
  • Modifica del DataBuffer per eseguire trasformazione di coordinate (questo in realtà funziona, ma è un'altra soluzione "sporco" perché il buffer non dovrebbe aver bisogno di conoscere il layout linea di scansione / pixel.)
  • Re-attuazione dei Raster e / o SampleModel interfacce da zero (a causa del controllo compatibilità modo è implementato (almeno nella Sun JDK), richiedendo sottoclassi specifiche di SampleModel così una classe BottomUpSampleModel wrapper generico non funzionerebbe.)
È stato utile?

Soluzione

ho scoperto che posso implementare questo utilizzando una sola nuova classe, che ho chiamato BottomUpComponentSampleModel. Si estende ComponentSampleModel e nega il valore del campo scanlineStride (che, fortunatamente, è protected anziché private) dopo chiamare il costruttore superclasse. Tutti i calcoli di indirizzi di pixel funzionano bene, anche se la convalida in Raster.createWritableRaster non (si può non rilevare se si dà una matrice che è troppo piccola), ma questo non è un problema serio.

Questo non è necessario con MultiPixelPackedSampleModel o SinglePixelPackedSampleModel, come fanno accettare un scanlineStride negativo. Non hanno offset della band, ma questo può essere lavorato intorno Impostando un offset sulla DataBuffer.

Altri suggerimenti

quello di avere la (o livello di accesso) applicazione fare la traduzione e lanciando lavoro sulla sua copia quando si accede alla piccola (ma difficile da prevedere) porzione di immagine?

ancora meglio, suona come l'applicazione non ha bisogno di visualizzare in realtà l'immagine? Perché preoccuparsi di voler capovolgere in primo luogo così sarebbe sembrato corretto sullo schermo? Basta scrivere la logica di lavorare sulla versione hai? Non c'è bisogno di avere un BufferedImage in questo modo sia, lavorare direttamente sulla matrice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top