2011-07-26 9 views
10

prima mi piacerebbe spiegare la situazione/requisiti che conducono alla domanda:alternativa puro Java per JAI ImageIO per il rilevamento di immagini CMYK

Nella nostra applicazione web, non siamo in grado di supportare le immagini CMYK (JPEG) dal IE 8 e sotto non possono visualizzarli. Quindi dobbiamo rilevare quando qualcuno vuole caricare tale immagine e negarla.

Sfortunatamente, ImageIO di Java non leggerà quelle immagini o non mi consentirebbe di ottenere lo spazio colore rilevato. Dal debug sembra che lo JPEGImageReader internamente riceva il codice dello spazio colore 11 (che significherebbe JCS_YCCK) ma non posso accedere in modo sicuro a tali informazioni.

Quando si interrogano il lettore per i tipi di immagine, non ottengo nulla per CMYK, quindi potrei assumere no image types = unsupported image.

Ho convertito l'immagine CMYK di origine in RGB utilizzando uno strumento di imaging per verificare se sarebbe quindi leggibile (ho provato a simulare i passi dell'amministratore quando ho ricevuto il messaggio "No CMYK supportato"). Tuttavia, JPEGImageReader non leggerà quell'immagine, dal momento che assume (commento nella fonte!) Spazio colore RGB a 3 componenti, ma l'intestazione dell'immagine riporta 4 componenti (forse RGBA o ARGB) e quindi viene lanciato uno IllegalArgumentException.

Quindi, ImageIO non è un'opzione in quanto non posso ottenere in modo affidabile lo spazio colore di un'immagine e non posso dire all'amministratore perché un'immagine altrimenti bella (può essere visualizzata dal browser) non sarebbe accettata a causa di un errore interno.

Questo mi ha portato a provare JAI ImageIO cui CLibJPEGImageReader fa un ottimo lavoro e corretto legge tutte le mie immagini di prova.

Tuttavia, poiché stiamo implementando la nostra applicazione in un JBoss che potrebbe ospitare anche altre applicazioni, vorremmo tenerle il più isolate possibile. AFAIK, avrei bisogno di installare JIO ImageIO su JRE o altrimenti rendere disponibili le librerie native per poterle usare, e quindi anche altre applicazioni potrebbero accedervi, il che potrebbe causare effetti collaterali (almeno avremmo testare molto per assicurarsi che non sia così).

Questa è la spiegazione per la domanda, e qui si tratta di nuovo: C'è un puro Java alternativa al JAI ImageIO che rileva in modo affidabile e possibilmente converte le immagini CMYK?

Grazie in anticipo,

Thomas

risposta

10

Ho trovato una soluzione che è ok per le nostre esigenze: Apache Commons Sanselan. Questa libreria legge le intestazioni JPEG in modo abbastanza veloce e preciso (almeno tutte le mie immagini di prova), nonché una serie di altri formati di immagine.

Lo svantaggio è che non leggerà i dati di immagine JPEG, ma posso farlo con gli strumenti di base di JRE.

immagini di lettura JPEG per la conversione è abbastanza facile (quelli che ImageIO rifiuta di leggere, anche):

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream(new File(pFilename))); 
BufferedImage sourceImg = decoder.decodeAsBufferedImage(); 

Poi, se Sanselan mi dice l'immagine è in realtà CMYK, ottengo raster immagine della sorgente e convertire me stesso:

for(/*each pixel in the raster, which is represented as int[4]*/) 
{ 
    double k = pixel[3]/255.0; 

    double r = (255.0 - pixel[0])*k; 
    double g = (255.0 - pixel[1])*k; 
    double b = (255.0 - pixel[2])*k; 
} 

Questo dà risultati abbastanza buoni nelle immagini RGB non troppo luminose o scure. Tuttavia, non sono sicuro del motivo per cui moltiplicare con k impedisce il ravvivamento. Il JPEG è in realtà decodificato nel codice nativo e la conversione CMYK-> RGB ho ottenuto qualcosa di diverso, ho appena provato il multiplo per vedere il risultato visivo.

Se qualcuno potesse far luce su questo, sarei grato.

+0

Ho riscontrato lo stesso problema con le immagini JAI e CMYK JPEG. Utilizzi questo approccio già in produzione? Com'è la tua esperienza? Suppongo che tu usi 'Sanselan.getImageInfo (...). GetColorType() == ImageInfo.COLOR_TYPE_CMYK' ([ImageInfo] (http://commons.apache.org/sanselan/api-release/org/apache/sanselan /ImageInfo.html)) per verificare se si tratta di un'immagine CMYK, giusto? –

+0

@bene Sì, stiamo prima controllando se Sanselan ha trovato un profilo ICC e, in tal caso, prende il suo tipo di spazio colore, ma se fallisce usiamo 'ImageInfo.getColorType()'. Lo stiamo utilizzando in produzione e non abbiamo avuto problemi finora, tuttavia, devo ammettere che al momento non stiamo gestendo molte immagini. In futuro avremo il nostro database multimediale che gestirà migliaia di immagini e quindi avremmo informazioni più affidabili sulla prontezza della produzione di tale approccio. Solo una nota a margine: la conversione di Tiffs CMYK produce alcune tinte evidenti e non siamo riusciti a sbarazzarcene. – Thomas

+1

Oggi ho colpito un'immagine in cui ICCProfile di Sanselan ha ColorSpaceType CMYK mentre ColorType di ImageInfo è RGB. Lo spazio cromatico è in realtà RGB. Mi chiedo se hai avuto lo stesso problema. –

2

Nella nostra applicazione web, non siamo in grado di supportare immagini CMYK (JPEG) dal IE 8 e al di sotto non li può visualizzare. Quindi abbiamo bisogno di rilevare quando qualcuno vuole caricare tale immagine e negarla.

non sono d'accordo con la vostra "Così abbiamo bisogno di rilevare quando qualcuno vuole caricare una tale immagine e negarlo". Una politica molto più user-friendly sarebbe quella di convertirlo in qualcosa di diverso da CMYK.

Il resto del post è un po 'confuso per quanto riguarda visto che chiedi sia per il rilevamento e la conversione, che sono due cose diverse. Ancora una volta, penso che la conversione dell'immagine sia molto più user-friendly.

Non c'è bisogno di scrivere in grassetto btw:

C'è qualche alternativa Java puro al JAI ImageIO che in modo affidabile rileva ed eventualmente converte le immagini CMYK?

Java puro Non lo so, ma ImageMagick funziona perfettamente per convertire l'immagine CMYK in RGB. Chiamare ImageMagick sul lato server da Java non è davvero complicato. Ho usato per farlo manualmente chiamando un processo esterno, ma al giorno d'oggi ci sono wrapper come JMagick e im4java.

+0

Per quanto riguarda la facilità d'uso: la conversione da CMYK a RGB a volte rallegra leggermente i colori e quindi vorremmo che l'utente la convertisse manualmente e confermasse che i colori sono ancora ok. In un'altra applicazione siamo liberi di convertire indipendentemente da questo, quindi ho chiesto entrambi. – Thomas

+0

'Non c'è bisogno di scrivere in grassetto btw:' - è stato solo per contrassegnare la domanda per coloro che non vogliono leggere la confusione tra :) – Thomas

+0

Relating 'ImageMagick': potrebbe essere un'alternativa anche se avremmo bisogno per installarlo pure. Grazie per questo suggerimento. – Thomas

4

Ho pubblicato un Java puro solution per leggere tutti i tipi di immagini JPEG e convertirli in RGB.

È costruito sui seguenti fatti:

  • Mentre ImageIO non può leggere immagini JPEG con CMYK come immagine tamponata, può leggere i dati dei pixel grezzi (raster).
  • Sanselan (o Apache Commons Imaging come viene chiamato ora) può essere utilizzato per leggere i dettagli delle immagini CMYK.
  • Ci sono immagini con valori CMYK invertiti (un vecchio bug di Photoshop).
  • Ci sono immagini con YCCK invece di CMYK (può essere facilmente convertito).
2

Attenzione a un altro post poiché Java 7 non consente di utilizzare direttamente l'implementazione di Sun senza parametri speciali come indicato in import com.sun.image.codec.jpeg.*.

Problemi correlati