Alternative Java Pure à JAI ImageIO pour la détection D'images CMJN
tout d'abord, j'aimerais expliquer la situation/les exigences qui ont mené à la question:
dans notre application Web, nous ne pouvons pas prendre en charge les images CMYK (JPEG) car IE 8 et ci-dessous ne peuvent pas les afficher. Nous devons donc détecter quand quelqu'un veut télécharger une telle image et la nier.
malheureusement, L'ImageIO de Java ne lira pas ces images ou ne me permettrait pas d'obtenir l'espace de couleur détecté. De débogage il semble que JPEGImageReader
obtient en interne le code d'espace de couleur 11 (qui signifierait JCS_YCCK
) mais je ne peux pas accéder à cette information en toute sécurité.
en interrogeant le lecteur pour les types d'image je n'obtiens rien pour CMYK, donc je pourrais supposer no image types = unsupported image
.
j'ai converti L'image CMYK source en RVB en utilisant un outil d'imagerie afin de tester si elle serait alors lisible (j'ai essayé de simuler les étapes de l'administrateur lors de la réception du message"NO CMYK supported"). Cependant, JPEGImageReader
ne se lirait pas cette image, puisqu'elle suppose (commentaire dans la source!)3-component RGB colour space mais l'en-tête d'image signale 4 components (peut-être RGBA ou ARGB) et donc un IllegalArgumentException
est lancé.
donc, ImageIO n'est pas une option car je ne peux pas obtenir de manière fiable l'espace de couleur d'une image et je ne peux pas dire à l'administrateur pourquoi une image autrement fine (elle peut être affichée par le navigateur) ne serait pas acceptée en raison d'une erreur interne.
cela m'a amené à essayer JAI ImageIO dont le CLibJPEGImageReader
fait un excellent travail et lit correctement toutes mes images de test.
cependant, puisque nous déployons notre application dans un JBoss qui pourrait héberger d'autres applications, nous aimerions les garder aussi isolées que possible. AFAIK, j'aurais besoin d'installer JAI ImageIO à la JRE ou autrement rendre les libs natifs disponibles afin de les utiliser, et donc d'autres applications pourraient obtenir l'accès à eux aussi, ce qui pourrait causer des effets secondaires (au moins nous aurions à tester beaucoup pour s'assurer que ce n'est pas le cas).
c'est l'explication de la question, et la voici qui revient: Existe-t-il une alternative Java pure à JAI ImageIO qui détecte de manière fiable et convertit éventuellement des images CMJN?
Merci d'avance,
Thomas
4 réponses
j'ai trouvé une solution qui convient à nos besoins: Apache Commons Sanselan . Cette bibliothèque lit les en-têtes JPEG assez rapidement et précis (au moins toutes mes images de test) ainsi qu'un certain nombre d'autres formats d'image.
l'inconvénient est qu'il ne lit pas les données image JPEG, mais je peux le faire avec les outils de base JRE.
lire des images JPEG pour la conversion est assez facile (ceux que ImageIO
refuse de lire, trop):
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream( new File(pFilename) ) );
BufferedImage sourceImg = decoder.decodeAsBufferedImage();
alors si Sanselan me dit que l'image est en fait CMYK, j'obtiens la trame de l'image source et je me convertis:
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;
}
cela donne de très bons résultats dans les images RVB n'étant pas trop clair ou sombre. Cependant, je ne suis pas sûr pourquoi la multiplication avec k
empêche l'éclaircissement. Le JPEG est en fait décodé en code natif et la conversion CMYK->RGB j'ai obtenu des États quelque chose de différent, j'ai juste essayé la multiplication pour voir le résultat visuel.
si quelqu'un pouvait nous éclairer là-dessus, je vous en serais reconnaissant.
j'ai posté un Java pur solution pour lire toutes sortes D'images JPEG et les convertir en RGB.
il est construit sur les faits suivants:
- alors Qu'ImageIO ne peut pas lire les images JPEG Avec CMYK comme une image tampon, il peut lire les données brutes de pixel (raster).
- Sanselan (ou Apache Commons Imaging comme on l'appelle maintenant) peut être utilisé pour lire les détails des images CMJN.
- il y a des images avec des valeurs CMJN inversées (un vieux bug Photoshop).
- il y a des images avec YCCK au lieu de CMYK (facilement convertibles).
dans notre application Web nous ne pouvons pas prendre en charge les images CMYK (JPEG) depuis IE 8 et inférieur ne peuvent pas les afficher. Nous devons donc détecter quand quelqu'un veut télécharger une telle image et la nier.
Je ne suis pas d'accord avec votre " nous devons donc détecter quand quelqu'un veut télécharger une telle image et la nier " ". Une politique beaucoup plus conviviale consisterait à la convertir en quelque chose d'autre que le CMJN.
Le reste de votre post est un peu confus à cet égard vu que vous demandez à la fois la détection et la conversion, qui sont deux choses différentes. Une fois de plus, je pense que la conversion de l'image est beaucoup plus convivial.
Pas besoin d'écrire en gras btw:
Existe-t-il une alternative Java pure à JAI ImageIO qui détecte et convertit éventuellement des images CMJN?
pur Java Je ne sais pas, mais ImageMagick fonctionne très bien pour convertir L'image CMYK en RVB. Appeler ImageMagick du côté serveur de Java n'est vraiment pas compliqué. J'avais l'habitude de le faire manuellement en appelant un processus externe mais aujourd'hui il y a des enveloppes comme JMagick et im4java .
méfiez-vous d'un autre post car le Java 7 ne permet pas d'utiliser directement L'implémentation de Sun sans paramètres spéciaux comme indiqué dans import com.soleil.image.codec.jpeg.* .