Les avis sur le DNG foisonnent, en bien comme en mal. Voici ma première question : perd-on des informations quand on convertit un RAW en DNG ?
Cet article fait partie d’une série consacrée au format DNG, introduite par la question : Le DNG, pour ou contre ?
Le DNG propose des avantages très intéressants mais comment être sûr de ne pas regretter un basculement intégral ? Au vu des innombrables discussions sur le net, je ne suis pas le seul à me cette poser. Toujours vagues et sans apporter de preuve ou une quelconque comparaison sur des bases concrètes, les réponses apportées par ces discussions ne me satisfont pas. Je couche donc sur ce papier virtuel le résultat de mes modestes recherches !
La question qui reste ouverte : les métadonnées
Les métadonnées, ces données qui permettent une foule d’automatisations et d’assistants qui nous (me) sont chers quand on traite des photos par milliers. Je n’insisterai jamais assez sur l’importance et l’avantage de métadonnées les plus complètes possible.
On sait donc qu’il y a une différence dans les métadonnées d’un RAW propriétaire tel qu’un ORF, CR2, ou un NEF, et de sa version DNG. Mais quelles sont ces différences et sont-elles assez importantes pour ne pas sauter le pas ?
Pour le savoir, j’ai réalisé une petite expérience. J’ai pris une de mes photos au hasard et je l’ai convertie en DNG, et ensuite j’ai collecté leurs métadonnées via ExifTool (si vous ne connaissez pas encore ExifTool et que les métadonnées sont l’une de vos préoccupations, je vous conseille d’y jeter un œil. Vraiment. Allez-y !).
À ce moment précis, vous avez le choix :
- soit la procédure que j’ai suivie vous intéresse et ça devient technique (et un peu long) ;
- soit vous vous en calez et voulez juste lire la conclusion. Si vous vous en calez, je ne vous en veux pas :D.
Le test
Si vous voulez essayer chez vous, dans le terminal (je suis sur OSX, si vous êtes sur Windows, lisez la doc :D) tapez la ligne de commande suivante :
exiftool -a -u -sort chemin/vers/mon/fichier
L’option -a signifie « on prend aussi les données dupliquées », -u, quant à elle, signifie « on prend aussi les données inconnues », bref on prend tout.
Ok, donc on a une vue sur les métadonnées mais il y en a des centaines. Pour les comparer, j’ai préféré écrire un script et j’ai utilisé une des options d’Exiftool : -json qui exporte les métadonnées au format JSON (très utile pour comparer après).
exiftool -a -u -json -sort chemin/vers/mon/fichier.CR2 > cr2.json exiftool -a -u -json -sort chemin/vers/mon/fichier.DNG > dng.json
J’ajoute aussi l’option -sort pour trier les métadonnées par ordre alphabétique, et l’instruction pour mettre le contenu généré dans un fichier (> … à la fin de la ligne).
Nous avons nos données dans des fichiers, prêtes à être analysées. J’utilise alors Javascript, parce qu’avec des librairies comme Underscore.JS, la comparaison de collections de données est juste trop facile. Mais vous le faites avec ce que vous voulez après tout :).
Ce qui nous intéresse, ce n’est pas ce qui est identique mais bien ce qui diffère. Je récupère donc l’intersection entre les deux collections de données, et la soustrait à chacune des collections.
var cr2Keys = _.keys(cr2); var dngKeys = _.keys(dng); var commonKeys = _.intersection(cr2Keys, dngKeys); var cr2OnlyKeys = _.difference(cr2Keys, commonKeys); var dngOnlyKeys = _.difference(dngKeys, commonKeys);
Je dispose donc de trois choses :
- La liste des données communes (386 au total) ;
- La liste des données spécifiques à mon CR2 (24) ;
- La liste des données spécifiques à mon DNG (88).
Il me faut une quatrième chose : séparer les données communes qui ont des valeurs identiques dans les deux collections de celles dont les valeurs diffèrent. Au préalable, je retire quelques données : SourceFile, Directory, FileAccessDate, FileInodeChangeDate, FileModifyDate, FileName, FilePermissions, ModifyDate. Pourquoi ? Parce que leurs différences tiennent soit de l’emplacement sur mon disque dur, soit du moment où j’ai converti le CR2 en DNG.
_.each(commonKeysWeCare, function(value) { if (cr2[value] === dng[value]) { … } else { … } }
J’obtiens donc :
- La liste des données communes dont les valeurs sont identiques de parts et d’autres, et donc on s’en fout (353) ;
- La liste des données communes dont les valeurs diffèrent (33).
L’analyse
Les 33 données communes dont les valeurs diffèrent
CR2 | DNG | |
BitsPerSample | 8 8 8 | 16 |
Compression | JPEG (old-style) | JPEG |
FOV | 55.0 deg | 54.4 deg |
FileSize | 20 MB | 16 MB |
FileType | CR2 | DNG |
FocalLength35efl | 35.0 mm (35 mm equivalent: 34.6 mm) | 35.0 mm (35 mm equivalent: 35.0 mm) |
FocalPlaneResolutionUnit | inches | cm |
FocalPlaneXResolution | 3810.584958 | 1520 |
FocalPlaneYResolution | 3815.899582 | 1520 |
HyperfocalDistance | 14.38 m | 14.56 m |
ImageHeight | 3648 | 3708 |
ImageSize | 5472×3648 | 5568×3708 |
ImageWidth | 5472 | 5568 |
Lens35efl | 16.0 – 35.0 mm (35 mm equivalent: 15.8 – 34.6 mm) | 16.0 – 35.0 mm (35 mm equivalent: 16.0 – 35.0 mm) |
LensInfo | 16-35mm f/0 | 16-35mm f/? |
MIMEType | image/x-canon-cr2 | image/x-adobe-dng |
PhotometricInterpretation | RGB | Color Filter Array |
PreviewImage | (Binary data 1162203 bytes, use -b option to extract) | (Binary data 25412 bytes, use -b option to extract) |
PreviewImageLength | 1162203 | 25412 |
PreviewImageStart | 87156 | 332826 |
RowsPerStrip | 309 | 171 |
SamplesPerPixel | 3 | 1 |
ShutterSpeedValue | 1/49 | 1/50 |
StripByteCounts | 18701091 | 131328 |
StripOffsets | 2109616 | 201498 |
Dans ces 33 données, il faut faire la part des choses entre ce qui est important et ce qui ne l’est pas.
- FileType, FileSize et MIMEType sont différents… sans blague ?
- PreviewImage, PreviewImageLength et PreviewImageStart, c’est juste le thumbnail qui est plus petit d’un côté que de l’autre.
- FOV, FocalLength35efl, Lens35efl, ShutterSpeedValue sont arrondis, et LensInfo a une différence minime.
- La Compression, JPEG Lossless, rien de neuf là dessus.
Par contre, ces points sont intéressants et mériteraient d’être éclaircis.
- En quoi la différence de BitsPerSample importe-t-elle ?
- À unités égales (FocalPlaneResolutionUnit), FocalPlaneXResolution et FocalPlaneYResolution sont-ils différents ?
- HyperfocalDistance, pourquoi est-ce différent d’un côté et de l’autre ? Est-ce dû à l’arrondi ?
- ImageSize (et par conséquent ImageHeight et ImageWidth) est plus grand dans le DNG, pourquoi ? Est-ce lié au fait que le 6D a un taux de couverture de ±97% du viewfinder ? Les dimensions du CR2 sont de ±98% de celles du DNG, donc sauf coïncidence, j’ai ma réponse.
- PhotometricInterpretation : quelles sont les différences entre RGB et Color Filter Array (CFA) et leur impact sur l’image ?
- À quoi correspondent RowsPerStrip, SamplesPerPixel, StripByteCounts et StripOffsets ?
Les 24 données spécifiques au CR2 source
Key | Value |
ComponentsConfiguration | Y, Cb, Cr, – |
Copyright | |
ExifImageHeight | 3648 |
ExifImageWidth | 5472 |
Exif_0xc5d8 | 1 |
Exif_0xc5d9 | 2 |
Exif_0xc5e0 | 1 |
Exif_0xc6c5 | 1 |
Exif_0xc6dc | 450 301 7 4 |
FlashpixVersion | 0100 |
GPSVersionID | 2.3.0.0 |
InteropIndex | R98 – DCF basic file (sRGB) |
InteropVersion | 0100 |
Rating | 0 |
RawImageSegmentation | 1 2784 2784 |
ResolutionUnit | inches |
SubSecModifyDate | 2014:07:30 15:11:46.96 |
SubSecTime | 96 |
ThumbnailImage | (Binary data 7110 bytes, use -b option to extract) |
ThumbnailLength | 7110 |
ThumbnailOffset | 80044 |
UserComment | |
XResolution | 72 |
YResolution | 72 |
Même chose, on peut y voir des choses peu importantes.
- ComponentsConfiguration est présent dans les métadonnées du DNG sous YCbCrSubSampling.
- Copyright et UserComment sont des champs qui ne sont pas remplis par mon boitier et ne sont donc pas importants pour moi.
- ExifImageHeight, ExifImageWidth, ResolutionUnit, et SubSecModifyDate sont des données redondantes avec ImageHeight, ImageWidth, FocalPlaneResolutionUnit et ModifyDate. SubSecTime ne m’intéresse pas.
- ThumbnailImage, ThumbnailLength et ThumbnailOffset sont redondants avec PreviewImage, PreviewImageLength et PreviewImageStart.
Et de nouvelles questions à creuser.
- À quoi correspondent les données Exif_0xc…, RawImageSegmentation, XResolution et YResolution ?
- FlashpixVersion, GPSVersionID, InteropIndex et InteropVersion sont-ils utilisés et si oui dans quels cas ?
- Rating peut être pratique quand on s’ennuie sur la route et que l’on mettre ce temps à profit, est-ce sauvé dans le DNG sous un autre label ?
Les 88 données spécifiques au DNG
Key | Value |
ActiveArea | 38 72 3708 5568 |
AnalogBalance | 1 1 1 |
AntiAliasStrength | 1 |
ApproximateFocusDistance | 0.38 |
AsShotNeutral | 0.497087 1 0.627067 |
BaselineExposure | 0.25 |
BaselineNoise | 0.8 |
BaselineSharpness | 1.25 |
BayerGreenSplit | 250 |
BestQualityScale | 1 |
BlackLevelRepeatDim | 2 2 |
CFALayout | Rectangular |
CFAPattern | [Red,Green][Green,Blue] |
CFAPattern2 | 0 1 1 2 |
CFAPlaneColor | Red,Green,Blue |
CFARepeatPatternDim | 2 2 |
CalibrationIlluminant1 | Standard Light A |
CalibrationIlluminant2 | D65 |
CameraCalibration1 | 1.0135 0 0 0 1 0 0 0 0.9852 |
CameraCalibration2 | 1.0135 0 0 0 1 0 0 0 0.9852 |
CameraCalibrationSig | com.adobe |
CameraSerialNumber | 033024004860 |
ColorMatrix1 | 0.7546 -0.1435 -0.0929 -0.3846 1.1488 0.2692 -0.0332 0.1209 0.637 |
ColorMatrix2 | 0.7034 -0.0804 -0.1014 -0.442 1.2564 0.2058 -0.0851 0.1994 0.5758 |
Creator | Karl Delandsheere |
CreatorTool | Adobe Photoshop Lightroom 5.5 (Macintosh) |
DNGBackwardVersion | 1.1.0.0 |
DNGLensInfo | 16-35mm f/? |
DNGVersion | 1.4.0.0 |
DateCreated | 2014:07:30 15:11:46.96 |
DefaultCropOrigin | 12 12 |
DefaultCropSize | 5472 3648 |
DefaultScale | 1 1 |
DerivedFromDocumentID | 27FBD1260B668C8AF1ACE4671A2BC5C2 |
DerivedFromOriginalDocumentID | 27FBD1260B668C8AF1ACE4671A2BC5C2 |
DocumentID | xmp.did:7c782ee2-d157-48ea-8aae-d828929eebfa |
Exif_0xc7aa | 256 |
Firmware | 1.1.3 |
FlashCompensation | 0 |
Format | image/dng |
ForwardMatrix1 | 0.7763 0.0065 0.1815 0.2364 0.8351 -0.0715 -0.0059 -0.4228 1.2538 |
ForwardMatrix2 | 0.7464 0.1044 0.1135 0.2648 0.9173 -0.182 0.0113 -0.2154 1.0292 |
HasCrop | false |
HistoryAction | derived,saved |
HistoryChanged | / |
HistoryInstanceID | xmp.iid:7c782ee2-d157-48ea-8aae-d828929eebfa |
HistoryParameters | converted from image/x-canon-cr2 to image/dng, saved to new location |
HistorySoftwareAgent | Adobe Photoshop Lightroom 5.5 (Macintosh) |
HistoryWhen | 2014:07:30 15:22:44+02:00 |
ImageNumber | 0 |
InstanceID | xmp.iid:7c782ee2-d157-48ea-8aae-d828929eebfa |
LinearResponseLimit | 1 |
MaxApertureValue | 2.8 |
MetadataDate | 2014:07:30 15:22:44+02:00 |
NewRawImageDigest | 4420f120b653471fd4cdc3e3868804ca |
NoiseProfile | 1.38033112077516e-05 1.41414007003259e-07 1.40749217975128e-05 1.421404607809e-07 1.4036774242771e-05 1.45716848609285e-07 |
OpcodeList2 | (Binary data 256 bytes, use -b option to extract) |
OriginalDocumentID | 27FBD1260B668C8AF1ACE4671A2BC5C2 |
OriginalRawFileName | IMG_7692.CR2 |
PreviewApplicationName | Adobe Photoshop Lightroom |
PreviewApplicationVersion | 5.5 |
PreviewColorSpace | 2 |
PreviewDateTime | 2014:07:30 15:22:44+02:00 |
PreviewSettingsDigest | cbaeb0aaf10e0f5ea515a7000c72e0a1 |
ProfileCalibrationSig | com.adobe |
ProfileCopyright | Copyright 2012 Adobe Systems, Inc. |
ProfileEmbedPolicy | Allow Copying |
ProfileHueSatMapData1 | (Binary data 137566 bytes, use -b option to extract) |
ProfileHueSatMapData2 | (Binary data 138373 bytes, use -b option to extract) |
ProfileHueSatMapDims | 90 30 1 |
ProfileLookTableData | (Binary data 89143 bytes, use -b option to extract) |
ProfileLookTableDims | 36 8 16 |
ProfileName | Adobe Standard |
RawDataUniqueID | 10383B18B0CFFFA3314789C216101FE7 |
ReferenceBlackWhite | 0 255 128 255 128 255 |
ShadowScale | 1 |
Software | Adobe Photoshop Lightroom 5.5 (Macintosh) |
SubfileType | Reduced-resolution image |
TileByteCounts | 7513 |
TileLength | 176 |
TileOffsets | 665020 |
TileWidth | 256 |
UniqueCameraModel | Canon EOS 6D |
WhiteLevel | 15000 |
XMPToolkit | Adobe XMP Core 5.5-c002 1.148022, 2012/07/15-18:06:45 |
YCbCrCoefficients | 0.299 0.587 0.114 |
YCbCrPositioning | Co-sited |
YCbCrSubSampling | YCbCr4:2:0 (2 2) |
La première chose à noter dans ce tableau, ce sont les données spécifiques au DNG qui sont soit des duplications (UniqueCameraModel, MaxApertureValue, …), soit des données d’historique ou sur le logiciel qui a généré le DNG. À noter que le DNG conserve les dimensions originales du CR2 dans les données DefaultCropOrigin et DefaultCropSize.
Mon inquiétude à l’origine de cette expérience était la perte d’information, pas le fait d’en avoir encore plus.
Bien qu’intéressantes, les données spécifiques au DNG ne pèsent pas pour moi dans la balance. Je ne vais donc pas passer en détail tout ce dernier tableau mais si vous avez des infos, elles sont les bienvenues :).
Conclusion
Sur les 410 données que mon CR2 embarquait, seulement 26 posent question avec divers niveaux d’importance. Et aucune d’entre elles ne représente une perte de donnée utile. L’expérience mérite bien sûr d’être reportée sur d’autres photos et d’autres formats RAW et je devrais peut-être développer ma façon de tester pour prendre plus de paramètres en compte. Mais le but était de voir si je perdrais des informations et la réponse est : oui et non.
La réponse est oui
Je perds apparemment certaines informations, le Rating n’est pas reporté dans le DNG. Mais est-ce parce qu’il n’était pas défini ? Si il l’était, serait-il présent dans les métadonnées du DNG ? Le UserComment est aussi manquant par exemple.
La réponse est non
Les données qui ne figurent pas dans le DNG ne me sont d’aucune importance (et encore, je n’ai pas approfondi la comparaison et les éventuelles traductions de valeurs). Je ne perds donc rien d’utile.
Quand j’analyse un DNG généré à partir d’un ORF (RAW de chez Olympus), je retrouve même des données telles que la focale utilisée pour la stabilisation d’image, cachées dans une foule d’autre données préfixées Olympus_ImageProcessing_ ! On peut donc dire que le passage d’information est assez complet.
Complément d’analyse
Pour les personnes utilisant des firmwares alternatifs (comme Magic Lantern sur Canon par exemple), ou des systèmes ajoutant des informations (gestion de timelapse, de pano, etc), il serait intéressant de faire des tests supplémentaires. Je n’ai pas de cas pratique à tester actuellement donc s’il y a des volontaires ;).
Et vous ?
Où en êtes-vous par rapport au DNG ? Votre avis m’intéresse !