Question

J'aimerais d'abord expliquer la situation/les exigences qui mènent à la question :

Dans notre application Web, nous ne pouvons pas prendre en charge les images CMJN (JPEG) car IE 8 et versions antérieures ne peuvent pas les afficher.Nous devons donc détecter quand quelqu’un souhaite télécharger une telle image et la refuser.

Malheureusement, ImageIO de Java ne lit pas ces images ou ne me permet pas d'obtenir l'espace colorimétrique détecté.D'après le débogage, il semble que JPEGImageReader obtient en interne le code d'espace colorimétrique 11 (ce qui signifierait JCS_YCCK) mais je ne peux pas accéder à ces informations en toute sécurité.

Lorsque j'interroge le lecteur sur les types d'images, je n'obtiens rien pour CMJN, donc je pourrais supposer no image types = unsupported image.

J'ai converti l'image CMJN source en RVB à l'aide d'un outil d'imagerie afin de tester si elle serait alors lisible (j'ai essayé de simuler les étapes de l'administrateur lorsque j'obtenais le message "Aucun CMJN pris en charge").Cependant, JPEGImageReader je ne lirais pas cette image, car elle suppose (commentaire dans la source !)Espace colorimétrique RVB à 3 composants mais l'en-tête de l'image rapporte 4 composants (peut-être RGBA ou ARGB) et donc un IllegalArgumentException Est lancé.

Ainsi, ImageIO n'est pas une option car je ne peux pas obtenir de manière fiable l'espace colorimétrique d'une image et je ne peux pas dire à l'administrateur pourquoi une image par ailleurs fine (elle peut être affichée par le navigateur) ne serait pas acceptée en raison de certains problèmes internes. erreur.

Cela m'a amené à essayer JAI ImageIO dont 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 également héberger d'autres applications, nous aimerions les garder aussi isolées que possible.AFAIK, je devrais installer JAI ImageIO sur le JRE ou rendre les bibliothèques natives disponibles afin de les utiliser, et ainsi d'autres applications pourraient également y accéder, ce qui pourrait provoquer 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 à nouveau :Existe-t-il une alternative Java pure à JAI ImageIO qui détecte et éventuellement convertit les images CMJN de manière fiable ?

Merci d'avance,

Thomas

Était-ce utile?

La solution

J'ai trouvé une solution qui convient à nos besoins : Apache Commons Sansélan.Cette bibliothèque lit les en-têtes JPEG assez rapidement et avec précision (au moins toutes mes images de test) ainsi qu'un certain nombre d'autres formats d'image.

L'inconvénient est qu'il ne lira pas les données d'image JPEG, mais je peux le faire avec les outils JRE de base.

La lecture des images JPEG pour la conversion est assez simple (celles qui ImageIO refuse de lire aussi) :

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

Ensuite, si Sanselan me dit que l'image est en fait CMJN, j'obtiens le raster de l'image source et 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 d'assez bons résultats dans les images RVB qui ne sont ni trop claires ni trop sombres.Cependant, je ne sais pas pourquoi multiplier par k empêche l'éclaircissement.Le JPEG est en fait décodé en code natif et la conversion CMJN-> RVB que j'ai obtenue indique quelque chose de différent, j'ai juste essayé la multiplication pour voir le résultat visuel.

Si quelqu'un pouvait faire la lumière à ce sujet, je lui en serais reconnaissant.

Autres conseils

J'ai posté un pur Java solution pour lire toutes sortes d'images JPEG et les convertir en RVB.

Il repose sur les faits suivants :

  • Bien qu'ImageIO ne puisse pas lire les images JPEG avec CMJN en tant qu'image tampon, il peut lire les données de pixels brutes (raster).
  • Sanselan (ou Apache Commons Imaging comme on l'appelle maintenant) peut être utilisé pour lire les détails des images CMJN.
  • Il existe des images avec des valeurs CMJN inversées (un vieux bug de Photoshop).
  • Il existe des images avec YCCK au lieu de CMJN (peuvent facilement être converties).

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.Ainsi, nous devons détecter quand quelqu'un veut télécharger une telle image et le nier.

je ne suis pas d'accord avec ton "Nous devons donc détecter quand quelqu'un souhaite télécharger une telle image et la refuser".Une politique beaucoup plus conviviale serait de le convertir en autre chose que CMJN.

Le reste de votre message est un peu déroutant à cet égard étant donné que vous demandez à la fois la détection et la conversion, qui sont deux choses différentes.Encore une fois, je pense que la conversion de l’image est beaucoup plus conviviale.

Pas besoin d'écrire en gras d'ailleurs :

Y a-t-il une alternative Java pure à Jai Imageio qui détecte et convertit éventuellement des images CMYK?

Java pur, je ne sais pas, mais ImageMagick fonctionne bien pour convertir les images CMJN en images RVB.Appel ImageMagick côté serveur depuis Java, ce n’est vraiment pas compliqué.Avant, je le faisais manuellement en appelant un processus externe, mais de nos jours, il existe des wrappers comme JMagick et im4java.

Attention à un autre post car Java 7 ne permet pas d'utiliser directement l'implémentation de Sun sans paramètres particuliers comme indiqué dans importer com.sun.image.codec.jpeg.*.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top