2017-04-20 3 views
2

Les images de notre site Web ne s'affichent pas dans Safari pour certains utilisateurs de Mac et elles indiquent ne voir aucune image ou image noire. Voici un exemple:Les images au format PNG ne s'affichent pas sur Mac Safari

http://s3-eu-west-2.amazonaws.com/bp18.boxcleverpress.com/Boxclever_logo_chartreuse.png

Ce que j'ai découvert est:

  • Images afficher sur PC
  • Images affichage sur certains Mac (j'ai un plus qui est OK)
  • Les images s'affichent sur les iPhones et les iPads
  • Les images sont au format PNG
  • J'ai optimisé l'im
  • Lorsque les images sont copiées sur Mac et ouvertes avec Adobe Photoshop, elles donnent l'erreur: le module de format de fichier ne peut pas analyser le fichier. obtenir cette erreur
  • Quand j'ai essayé d'ouvrir le fichier optimisé dans Photoshop sous Windows, je reçois l'erreur IDAT: des données incorrectes vérifier

je remplacerai les images optimisées avec les non optimisé mais je ne sais pas si ce problème est avec les bibliothèques d'images pngtastic ou Adobe ou autre chose.

+0

Le remplacement at-il résolu le problème? Je reçois aussi des plaintes des utilisateurs de Safari pour ne pas voir de fichiers PNG, mais ceux-ci ont été créés avec 'imagecreatetruecolor' en PHP (bibliothèque GD standard), et non 'optimisés' de quelque façon que ce soit. –

+0

@Marten - oui le remplacement par les images non optimisées a permis de les voir. J'espère avoir un peu de temps pour approfondir le problème et rendre compte de ce que je trouve. –

Répondre

2

Le problème réside dans Zopfli.java, inclus par pngtastic.

Il utilise ce code Java pour calculer la somme de contrôle Adler-32:

/** 
* Calculates the adler32 checksum of the data 
*/ 
private static int adler32(byte[] data) { 
    int s1 = 1; 
    int s2 = 1 >> 16; 
    int i = 0; 
    while (i < data.length) { 
     int tick = Math.min(data.length, i + 1024); 
     while (i < tick) { 
      s1 += data[i++]; 
      s2 += s1; 
     } 
     s1 %= 65521; 
     s2 %= 65521; 
    } 

    return (s2 << 16) | s1; 
} 

Cependant, byte s en Java sont always signed, et il peut revenir si une valeur de contrôle erronée pour certaines entrées de données. En outre, les déclarations nues int pour s1 et s2 provoquent d'autres complications.

Avec (ma version C) le même code et data explicitement déclarés comme signed char et les deux s1 et s2 que signed int, je reçois une mauvaise somme de contrôle FFFF9180 - exactement celui de votre PNG endommagé.

Si je change la déclaration pour utiliser unsigned char et unsigned int, il renvoie à nouveau la somme de contrôle correcte 1BCD6EB2.


Le original C code pour la somme de contrôle Adler-32 Zöpfli utilise unsigned types partout, donc il est tout simplement l'implémentation Java qui souffre de cette situation.

+1

Merci pour vos investigations! J'ai signalé le problème au projet pngtastic: https://github.com/depsypher/pngtastic/issues/13 –

+0

Merci d'avoir suivi ce problème! J'ai poussé une nouvelle version de pngtastic avec un correctif basé sur ces résultats. – depsypher

1

Le problème semble être dû à l'utilisation de la compression zopfli dans les fichiers PNG que j'ai optimisés en utilisant pngtastic. La solution de contournement consiste à utiliser une option de compression pngtastic différente et les fichiers PNG sont alors lisibles dans Photoshop. L'utilisation d'un algorithme de compression différent entraînera une optimisation moindre. Je ne suis pas sûr pourquoi la compression de zopfli est un problème, il pourrait y avoir une faute dans mon code (bien que le même code fonctionne bien quand seulement l'option de zopli est changée), dans pngtastic, ou ce MacOS et Adobe ne supporte pas zopfli.

@ usr2564301 a fait quelques recherches et il semble que la somme de contrôle Adler-32 sur les données compressées dans mon exemple d'image est incorrecte. usr2564301 a également testé le code pngtastic et l'a trouvé pour produire la somme de contrôle correcte. Le problème pourrait être dans la façon dont je gère l'bytestream de pngtastic.

Le code ci-dessous exécute l'optimisation PNG en utilisant pngtastic (com.googlecode.pngtastic.core)

public static final String OPT_ZOPFLI = "zopfli"; 
public static final String OPT_DEFAULT = "default"; 
public static final String OPT_IMAGEOPTIM = "imageoptim"; 

private String optimization = OPT_ZOPFLI; 

public void optimizePng(File infile, String out) { 

    final InputStream in; 
    try { 
     in = new BufferedInputStream(new FileInputStream(infile)); 
     final PngImage image = new PngImage(in); 

     // optimize 
     final PngOptimizer optimizer = new PngOptimizer(); 

     optimizer.setCompressor(optimization, 1); 
     final PngImage optimizedImage = optimizer.optimize(image, false, 9); 

     // export the optimized image to a new file 
     final ByteArrayOutputStream optimizedBytes = new ByteArrayOutputStream(); 
     optimizedImage.writeDataOutputStream(optimizedBytes); 
     optimizedImage.export(out, optimizedBytes.toByteArray()); 

     } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
+1

Très intéressant. Est-ce que ces images passent 'pngcheck'? – usr2564301

+1

Bon point. C'était l'indice qui m'a conduit à ma solution de contournement. Quand j'exécute pngcheck sur le fichier, j'obtiens l'erreur: "zlib: gonfle l'erreur = -3" ce qui m'a suggéré d'essayer une compression différente, mais je ne sais pas quel est le problème avec zopfli, ou pourquoi certaines machines ou applications peut le lire. –

+1

C'est une source de préoccupation - et pas seulement pour les utilisateurs PNG. Il est affirmé que "... Zopfli est compatible avec la compression bit-stream utilisée en gzip, Zip, PNG, ..." (en moins de mots: Flate) et votre expérience montre que ce n'est pas le cas. Mark Adler est un habitué et il pourrait bien être intéressé. – usr2564301