¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Extracción de metadatos en imágenes
Módulo perteneciente al curso Python avanzado para proyectos de seguridad
Exiftool es una aplicación de código abierto que permite leer, escribir y manipular metadatos de imágenes, audio y video.
Se trata de una aplicación que nos permite visualizar los metadatos de una gran cantidad de formatos de imágenes, como AWR, ASF, SVG, TIFF, BMP, CRW, PSD, GIF, XMP, JP2, JPEG, DNG y unos cuantos más. Y en cuanto a los formatos de metadatos soportados podemos mencionar el EXIF, GPS, IPTC, XMP, Kodak, Rico, Adobe, Vorbis, JPEG 2000, Ducky, QuickTime, Matroska y DjVu entre otros.
La aplicación está disponible para Windows, Mac OS X y LInux.
En el caso de una distribución basada en Debian, podríamos instalarla con el comando:
$ sudo apt-get install libimage-exiftool-perl</strong>
Una vez instalada, para su ejecución bastaría con pasar por parámetro la ruta de la imagen:
$ exiftool images/image.jpg</strong>
IMAAAAAAAAAAAAAAAAAAAAAAAAAAAAGEN
Extracción de metadatos con el módulo PIL.ExifTags
Uno de los principales módulos que encontramos dentro de Python para el procesamiento y manipulación de imágenes es PIL.
PIL permite extraer los metadatos de imágenes en formato EXIF. Exif (Exchange Image File Format) es una especificación que indica las reglas que deben seguirse cuando vamos a guardar imágenes. Esta especificación es aplicada hoy en día en la mayoría de dispositivos móviles y cámaras digitales.
El módulo PIL.ExifTags permite extraer la información de estas etiquetas. ExifTags contiene una estructura de diccionario con constantes y nombres para muchas etiquetas EXIF conocidas.
Este módulo proporciona 2 clases con las que trabajar:
PIL.ExifTags.TAGS. Permite extraer la etiquetas más comunes almacenadas en la imagen.PIL.ExifTags.GPSTAGS. Permite extraer las etiquetas relacionadas con información de geolocalización.
Por ejemplo, podemos ver todas las etiquetas de las cuales podemos extraer información con el método TAGS.values():
>>> from PIL.ExifTags import TAGS >>> print(TAGS.values()) dict_values(['ProcessingSoftware', 'NewSubfileType', 'SubfileType', 'ImageWidth', 'ImageLength', 'BitsPerSample', 'Compression', 'PhotometricInterpretation', 'Thresholding', 'CellWidth', 'CellLength', 'FillOrder', 'DocumentName', 'ImageDescription', 'Make', 'Model', 'StripOffsets', 'Orientation', 'SamplesPerPixel', 'RowsPerStrip', 'StripByteCounts', 'MinSampleValue', 'MaxSampleValue', 'XResolution', 'YResolution', 'PlanarConfiguration', 'PageName', 'FreeOffsets', 'FreeByteCounts', 'GrayResponseUnit', 'GrayResponseCurve', 'T4Options', 'T6Options', 'ResolutionUnit', 'PageNumber', 'TransferFunction', 'Software', 'DateTime', 'Artist', 'HostComputer', 'Predictor', 'WhitePoint', 'PrimaryChromaticities', 'ColorMap', 'HalftoneHints', 'TileWidth', 'TileLength', 'TileOffsets', 'TileByteCounts', 'SubIFDs', 'InkSet', 'InkNames', 'NumberOfInks', 'DotRange', 'TargetPrinter', 'ExtraSamples', 'SampleFormat', 'SMinSampleValue', 'SMaxSampleValue', 'TransferRange', 'ClipPath', 'XClipPathUnits', 'YClipPathUnits', 'Indexed', 'JPEGTables', 'OPIProxy', 'JPEGProc', 'JpegIFOffset', 'JpegIFByteCount', 'JpegRestartInterval', 'JpegLosslessPredictors', 'JpegPointTransforms', 'JpegQTables', 'JpegDCTables', 'JpegACTables', 'YCbCrCoefficients', 'YCbCrSubSampling', 'YCbCrPositioning', 'ReferenceBlackWhite', 'XMLPacket', 'RelatedImageFileFormat', 'RelatedImageWidth', 'RelatedImageLength', 'Rating', 'RatingPercent', 'ImageID', 'CFARepeatPatternDim', 'CFAPattern', 'BatteryLevel', 'Copyright', 'ExposureTime', 'FNumber', 'IPTCNAA', 'ImageResources', 'ExifOffset', 'InterColorProfile', 'ExposureProgram', 'SpectralSensitivity', 'GPSInfo', 'ISOSpeedRatings', 'OECF', 'Interlace', 'TimeZoneOffset', 'SelfTimerMode', 'ExifVersion', 'DateTimeOriginal', 'DateTimeDigitized', 'ComponentsConfiguration', 'CompressedBitsPerPixel', 'ShutterSpeedValue', 'ApertureValue', 'BrightnessValue', 'ExposureBiasValue', 'MaxApertureValue', 'SubjectDistance', 'MeteringMode', 'LightSource', 'Flash', 'FocalLength', 'FlashEnergy', 'SpatialFrequencyResponse', 'Noise', 'ImageNumber', 'SecurityClassification', 'ImageHistory', 'SubjectLocation', 'ExposureIndex', 'TIFF/EPStandardID', 'MakerNote', 'UserComment', 'SubsecTime', 'SubsecTimeOriginal', 'SubsecTimeDigitized', 'XPTitle', 'XPComment', 'XPAuthor', 'XPKeywords', 'XPSubject', 'FlashPixVersion', 'ColorSpace', 'ExifImageWidth', 'ExifImageHeight', 'RelatedSoundFile', 'ExifInteroperabilityOffset', 'FlashEnergy', 'SpatialFrequencyResponse', 'FocalPlaneXResolution', 'FocalPlaneYResolution', 'FocalPlaneResolutionUnit', 'SubjectLocation', 'ExposureIndex', 'SensingMethod', 'FileSource', 'SceneType', 'CFAPattern', 'CustomRendered', 'ExposureMode', 'WhiteBalance', 'DigitalZoomRatio', 'FocalLengthIn35mmFilm', 'SceneCaptureType', 'GainControl', 'Contrast', 'Saturation', 'Sharpness', 'DeviceSettingDescription', 'SubjectDistanceRange', 'ImageUniqueID', 'CameraOwnerName', 'BodySerialNumber', 'LensSpecification', 'LensMake', 'LensModel', 'LensSerialNumber', 'Gamma', 'PrintImageMatching', 'DNGVersion', 'DNGBackwardVersion', 'UniqueCameraModel', 'LocalizedCameraModel', 'CFAPlaneColor', 'CFALayout', 'LinearizationTable', 'BlackLevelRepeatDim', 'BlackLevel', 'BlackLevelDeltaH', 'BlackLevelDeltaV', 'WhiteLevel', 'DefaultScale', 'DefaultCropOrigin', 'DefaultCropSize', 'ColorMatrix1', 'ColorMatrix2', 'CameraCalibration1', 'CameraCalibration2', 'ReductionMatrix1', 'ReductionMatrix2', 'AnalogBalance', 'AsShotNeutral', 'AsShotWhiteXY', 'BaselineExposure', 'BaselineNoise', 'BaselineSharpness', 'BayerGreenSplit', 'LinearResponseLimit', 'CameraSerialNumber', 'LensInfo', 'ChromaBlurRadius', 'AntiAliasStrength', 'ShadowScale', 'DNGPrivateData', 'MakerNoteSafety', 'CalibrationIlluminant1', 'CalibrationIlluminant2', 'BestQualityScale', 'RawDataUniqueID', 'OriginalRawFileName', 'OriginalRawFileData', 'ActiveArea', 'MaskedAreas', 'AsShotICCProfile', 'AsShotPreProfileMatrix', 'CurrentICCProfile', 'CurrentPreProfileMatrix', 'ColorimetricReference', 'CameraCalibrationSignature', 'ProfileCalibrationSignature', 'AsShotProfileName', 'NoiseReductionApplied', 'ProfileName', 'ProfileHueSatMapDims', 'ProfileHueSatMapData1', 'ProfileHueSatMapData2', 'ProfileToneCurve', 'ProfileEmbedPolicy', 'ProfileCopyright', 'ForwardMatrix1', 'ForwardMatrix2', 'PreviewApplicationName', 'PreviewApplicationVersion', 'PreviewSettingsName', 'PreviewSettingsDigest', 'PreviewColorSpace', 'PreviewDateTime', 'RawImageDigest', 'OriginalRawFileDigest', 'SubTileBlockSize', 'RowInterleaveFactor', 'ProfileLookTableDims', 'ProfileLookTableData', 'OpcodeList1', 'OpcodeList2', 'OpcodeList3', 'NoiseProfile'])
De la misma forma podemos las etiquetas relacionadas con geolocalización con el método GPSTAGS.values():
>>> from PIL.ExifTags import GPSTAGS >>> print(GPSTAGS.values()) dict_values(['GPSVersionID', 'GPSLatitudeRef', 'GPSLatitude', 'GPSLongitudeRef', 'GPSLongitude', 'GPSAltitudeRef', 'GPSAltitude', 'GPSTimeStamp', 'GPSSatellites', 'GPSStatus', 'GPSMeasureMode', 'GPSDOP', 'GPSSpeedRef', 'GPSSpeed', 'GPSTrackRef', 'GPSTrack', 'GPSImgDirectionRef', 'GPSImgDirection', 'GPSMapDatum', 'GPSDestLatitudeRef', 'GPSDestLatitude', 'GPSDestLongitudeRef', 'GPSDestLongitude', 'GPSDestBearingRef', 'GPSDestBearing', 'GPSDestDistanceRef', 'GPSDestDistance', 'GPSProcessingMethod', 'GPSAreaInformation', 'GPSDateStamp', 'GPSDifferential', 'GPSHPositioningError'])
Obtener los metadatos EXIF de una imagen
<p>Primero importamos los módulos PIL y PIL.ExifTags. PIL es un módulo de procesamiento de imágenes en Python que soporta diferentes formatos de archivo y tiene una poderosa capacidad de procesamiento de imágenes.</p>
<p>Para obtener la información de EXIF tags de una imagen se puede utilizar el método <strong>_getexif()</strong> del objeto imagen.</p>
<p>Este método nos devuelve una estructura diccionario que podemos recorrer con el método <strong>items().</strong></p>
<p>Puede encontrar el siguiente código en el archivo <strong>get_exif_tags.py</strong>:</p>
from PIL import Image from PIL.ExifTags import TAGS print(Image.open('images/image.jpg')._getexif()) for (key,value) in Image.open('images/image.jpg')._getexif().items(): print('%s = %s' % (TAGS.get(key), value))
<p>Por ejemplo, podemos tener una función donde a partir de la ruta de la imagen nos devuelva información de EXIF tags.</p>
<p>Puede encontrar el siguiente código en el archivo <strong>extractDataFromImages.py:</strong></p>
def get_exif_metadata(image_path): exifData = {} image = Image.open(image_path) if hasattr(image, '_getexif'): exifinfo = image._getexif() if exifinfo is not None: for tag, value in exifinfo.items(): decoded = TAGS.get(tag, tag) exifData[decoded] = value decode_gps_info2(exifData) return exifData
