Exemple #1
0
def test_exif_gps_data():
    '''
    Test extractiion of GPS data
    '''
    result = extract_exif(GPS_JPG)
    gps = get_gps_data(result)

    assert gps == {
        'latitude': 59.336666666666666,
        'direction': 25.674046740467404,
        'altitude': 37.64365671641791,
        'longitude': 18.016166666666667}
Exemple #2
0
def test_exif_no_exif():
    """
    Test an image without exif
    """
    result = extract_exif(EMPTY_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    assert result == {}
    assert clean == {}
    assert gps == {}
    assert useful == {}
Exemple #3
0
def test_exif_bad_image():
    """
    Test EXIF extraction from a faithful, but bad image
    """
    result = extract_exif(BAD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    assert result == {}
    assert clean == {}
    assert gps == {}
    assert useful == {}
Exemple #4
0
def test_exif_gps_data():
    """
    Test extractiion of GPS data
    """
    result = extract_exif(GPS_JPG)
    gps = get_gps_data(result)

    assert gps == {
        "latitude": 59.336666666666666,
        "direction": 25.674046740467404,
        "altitude": 37.64365671641791,
        "longitude": 18.016166666666667,
    }
Exemple #5
0
def test_exif_image_orientation():
    """
    Test image reorientation based on EXIF data
    """
    result = extract_exif(GOOD_JPG)

    image = exif_fix_image_orientation(Image.open(GOOD_JPG), result)

    # Are the dimensions correct?
    assert image.size == (428, 640)

    # If this pixel looks right, the rest of the image probably will too.
    assert_in(image.getdata()[10000], ((41, 28, 11), (43, 27, 11)))
Exemple #6
0
def process_image(proc_state):
    """Code to process an image. Will be run by celery.

    A Workbench() represents a local tempory dir. It is automatically
    cleaned up when this function exits.
    """
    entry = proc_state.entry
    workbench = proc_state.workbench

    # Conversions subdirectory to avoid collisions
    conversions_subdir = os.path.join(
        workbench.dir, 'conversions')
    os.mkdir(conversions_subdir)

    queued_filename = proc_state.get_queued_filename()
    name_builder = FilenameBuilder(queued_filename)

    # EXIF extraction
    exif_tags = extract_exif(queued_filename)
    gps_data = get_gps_data(exif_tags)

    # Always create a small thumbnail
    resize_tool(proc_state, True, 'thumb',
                name_builder.fill('{basename}.thumbnail{ext}'),
                conversions_subdir, exif_tags)

    # Possibly create a medium
    resize_tool(proc_state, False, 'medium',
                name_builder.fill('{basename}.medium{ext}'),
                conversions_subdir, exif_tags)

    # Copy our queued local workbench to its final destination
    proc_state.copy_original(name_builder.fill('{basename}{ext}'))

    # Remove queued media file from storage and database
    proc_state.delete_queue_file()

    # Insert exif data into database
    exif_all = clean_exif(exif_tags)

    if len(exif_all):
        entry.media_data_init(exif_all=exif_all)

    if len(gps_data):
        for key in list(gps_data.keys()):
            gps_data['gps_' + key] = gps_data.pop(key)
        entry.media_data_init(**gps_data)
Exemple #7
0
def test_exif_image_orientation():
    '''
    Test image reorientation based on EXIF data
    '''
    result = extract_exif(GOOD_JPG)

    image = exif_fix_image_orientation(
        Image.open(GOOD_JPG),
        result)

    # Are the dimensions correct?
    assert image.size in ((428, 640), (640, 428))

    # If this pixel looks right, the rest of the image probably will too.
    # It seems different values are being seen on different platforms/systems
    # as of ccca39f1 it seems we're adding to the list those which are seen.
    assert_in(image.getdata()[10000],
              ((37, 23, 14), (41, 28, 11), (43, 27, 11))
              )
    def common_setup(self):
        """
        Set up the workbench directory and pull down the original file
        """
        self.image_config = mgg.global_config[
            'media_type:mediagoblin.media_types.image']

        ## @@: Should this be two functions?
        # Conversions subdirectory to avoid collisions
        self.conversions_subdir = os.path.join(
            self.workbench.dir, 'convirsions')
        os.mkdir(self.conversions_subdir)

        # Pull down and set up the processing file
        self.process_filename = get_process_filename(
            self.entry, self.workbench, self.acceptable_files)
        self.name_builder = FilenameBuilder(self.process_filename)

        # Exif extraction
        self.exif_tags = extract_exif(self.process_filename)
Exemple #9
0
def test_exif_extraction():
    '''
    Test EXIF extraction from a good image
    '''
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) == 56

    # Do we have clean data?
    assert len(clean) == 53

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?
    assert useful == {
        'EXIF Flash': {
            'field_type': 3,
            'printable': u'Flash did not fire',
            'field_offset': 380,
            'tag': 37385,
            'values': [0],
            'field_length': 2},
        'EXIF ExposureTime': {
            'field_type': 5,
            'printable': '1/125',
            'field_offset': 700,
            'tag': 33434,
            'values': [[1, 125]],
            'field_length': 8},
        'EXIF FocalLength': {
            'field_type': 5,
            'printable': '18',
            'field_offset': 780,
            'tag': 37386,
            'values': [[18, 1]],
            'field_length': 8},
        'Image Model': {
            'field_type': 2,
            'printable': 'NIKON D80',
            'field_offset': 152,
            'tag': 272,
            'values': 'NIKON D80',
            'field_length': 10},
        'Image Make': {
            'field_type': 2,
            'printable': 'NIKON CORPORATION',
            'field_offset': 134,
            'tag': 271,
            'values': 'NIKON CORPORATION',
            'field_length': 18},
        'EXIF ExposureMode': {
            'field_type': 3,
            'printable': 'Manual Exposure',
            'field_offset': 584,
            'tag': 41986,
            'values': [1],
            'field_length': 2},
        'EXIF ISOSpeedRatings': {
            'field_type': 3,
            'printable': '100',
            'field_offset': 260,
            'tag': 34855,
            'values': [100],
            'field_length': 2},
        'EXIF FNumber': {
            'field_type': 5,
            'printable': '10',
            'field_offset': 708,
            'tag': 33437,
            'values': [[10, 1]],
            'field_length': 8}}
Exemple #10
0
    proc_state.copy_original(name_builder.fill('{basename}{ext}'))

    # Remove queued media file from storage and database
    proc_state.delete_queue_file()

    # Insert exif data into database
    exif_all = clean_exif(exif_tags)

    if len(exif_all):
        entry.media_data_init(exif_all=exif_all)

    if len(gps_data):
        for key in list(gps_data.keys()):
            gps_data['gps_' + key] = gps_data.pop(key)
        entry.media_data_init(**gps_data)


if __name__ == '__main__':
    import sys
    import pprint

    pp = pprint.PrettyPrinter()

    result = extract_exif(sys.argv[1])
    gps = get_gps_data(result)
    clean = clean_exif(result)
    useful = get_useful(clean)

    print pp.pprint(
        clean)
Exemple #11
0
def test_exif_extraction():
    """
    Test EXIF extraction from a good image
    """
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) == 56

    # Do we have clean data?
    assert len(clean) == 53

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?
    assert useful == {
        "EXIF Flash": {
            "field_type": 3,
            "printable": u"Flash did not fire",
            "field_offset": 380,
            "tag": 37385,
            "values": [0],
            "field_length": 2,
        },
        "EXIF ExposureTime": {
            "field_type": 5,
            "printable": "1/125",
            "field_offset": 700,
            "tag": 33434,
            "values": [[1, 125]],
            "field_length": 8,
        },
        "EXIF FocalLength": {
            "field_type": 5,
            "printable": "18",
            "field_offset": 780,
            "tag": 37386,
            "values": [[18, 1]],
            "field_length": 8,
        },
        "Image Model": {
            "field_type": 2,
            "printable": "NIKON D80",
            "field_offset": 152,
            "tag": 272,
            "values": "NIKON D80",
            "field_length": 10,
        },
        "Image Make": {
            "field_type": 2,
            "printable": "NIKON CORPORATION",
            "field_offset": 134,
            "tag": 271,
            "values": "NIKON CORPORATION",
            "field_length": 18,
        },
        "EXIF ExposureMode": {
            "field_type": 3,
            "printable": "Manual Exposure",
            "field_offset": 584,
            "tag": 41986,
            "values": [1],
            "field_length": 2,
        },
        "EXIF ISOSpeedRatings": {
            "field_type": 3,
            "printable": "100",
            "field_offset": 260,
            "tag": 34855,
            "values": [100],
            "field_length": 2,
        },
        "EXIF FNumber": {
            "field_type": 5,
            "printable": "10",
            "field_offset": 708,
            "tag": 33437,
            "values": [[10, 1]],
            "field_length": 8,
        },
    }
def test_exif_extraction():
    '''
    Test EXIF extraction from a good image
    '''
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) >= 50

    # Do we have clean data?
    assert len(clean) >= 50

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?

    expected = OrderedDict({
        'EXIF CVAPattern': {
            'field_length': 8,
            'field_offset': 26224,
            'field_type': 7,
            'printable': '[0, 2, 0, 2, 1, 2, 0, 1]',
            'tag': 41730,
            'values': [0, 2, 0, 2, 1, 2, 0, 1]
        },
        'EXIF ColorSpace': {
            'field_length': 2,
            'field_offset': 476,
            'field_type': 3,
            'printable': 'sRGB',
            'tag': 40961,
            'values': [1]
        },
        'EXIF ComponentsConfiguration': {
            'field_length': 4,
            'field_offset': 308,
            'field_type': 7,
            'printable': 'YCbCr',
            'tag': 37121,
            'values': [1, 2, 3, 0]
        },
        'EXIF CompressedBitsPerPixel': {
            'field_length': 8,
            'field_offset': 756,
            'field_type': 5,
            'printable': '4',
            'tag': 37122,
            'values': [[4, 1]]
        },
        'EXIF Contrast': {
            'field_length': 2,
            'field_offset': 656,
            'field_type': 3,
            'printable': 'Soft',
            'tag': 41992,
            'values': [1]
        },
        'EXIF CustomRendered': {
            'field_length': 2,
            'field_offset': 572,
            'field_type': 3,
            'printable': 'Normal',
            'tag': 41985,
            'values': [0]
        },
        'EXIF DateTimeDigitized': {
            'field_length': 20,
            'field_offset': 736,
            'field_type': 2,
            'printable': '2011:06:22 12:20:33',
            'tag': 36868,
            'values': '2011:06:22 12:20:33'
        },
        'EXIF DateTimeOriginal': {
            'field_length': 20,
            'field_offset': 716,
            'field_type': 2,
            'printable': '2011:06:22 12:20:33',
            'tag': 36867,
            'values': '2011:06:22 12:20:33'
        },
        'EXIF DigitalZoomRatio': {
            'field_length': 8,
            'field_offset': 26232,
            'field_type': 5,
            'printable': '1',
            'tag': 41988,
            'values': [[1, 1]]
        },
        'EXIF ExifImageLength': {
            'field_length': 2,
            'field_offset': 500,
            'field_type': 3,
            'printable': '2592',
            'tag': 40963,
            'values': [2592]
        },
        'EXIF ExifImageWidth': {
            'field_length': 2,
            'field_offset': 488,
            'field_type': 3,
            'printable': '3872',
            'tag': 40962,
            'values': [3872]
        },
        'EXIF ExifVersion': {
            'field_length': 4,
            'field_offset': 272,
            'field_type': 7,
            'printable': '0221',
            'tag': 36864,
            'values': [48, 50, 50, 49]
        },
        'EXIF ExposureBiasValue': {
            'field_length': 8,
            'field_offset': 764,
            'field_type': 10,
            'printable': '0',
            'tag': 37380,
            'values': [[0, 1]]
        },
        'EXIF ExposureMode': {
            'field_length': 2,
            'field_offset': 584,
            'field_type': 3,
            'printable': 'Manual Exposure',
            'tag': 41986,
            'values': [1]
        },
        'EXIF ExposureProgram': {
            'field_length': 2,
            'field_offset': 248,
            'field_type': 3,
            'printable': 'Manual',
            'tag': 34850,
            'values': [1]
        },
        'EXIF ExposureTime': {
            'field_length': 8,
            'field_offset': 700,
            'field_type': 5,
            'printable': '1/125',
            'tag': 33434,
            'values': [[1, 125]]
        },
        'EXIF FNumber': {
            'field_length': 8,
            'field_offset': 708,
            'field_type': 5,
            'printable': '10',
            'tag': 33437,
            'values': [[10, 1]]
        },
        'EXIF FileSource': {
            'field_length': 1,
            'field_offset': 536,
            'field_type': 7,
            'printable': 'Digital Camera',
            'tag': 41728,
            'values': [3]
        },
        'EXIF Flash': {
            'field_length': 2,
            'field_offset': 380,
            'field_type': 3,
            'printable': 'Flash did not fire',
            'tag': 37385,
            'values': [0]
        },
        'EXIF FlashPixVersion': {
            'field_length': 4,
            'field_offset': 464,
            'field_type': 7,
            'printable': '0100',
            'tag': 40960,
            'values': [48, 49, 48, 48]
        },
        'EXIF FocalLength': {
            'field_length': 8,
            'field_offset': 780,
            'field_type': 5,
            'printable': '18',
            'tag': 37386,
            'values': [[18, 1]]
        },
        'EXIF FocalLengthIn35mmFilm': {
            'field_length': 2,
            'field_offset': 620,
            'field_type': 3,
            'printable': '27',
            'tag': 41989,
            'values': [27]
        },
        'EXIF GainControl': {
            'field_length': 2,
            'field_offset': 644,
            'field_type': 3,
            'printable': 'None',
            'tag': 41991,
            'values': [0]
        },
        'EXIF ISOSpeedRatings': {
            'field_length': 2,
            'field_offset': 260,
            'field_type': 3,
            'printable': '100',
            'tag': 34855,
            'values': [100]
        },
        'EXIF InteroperabilityOffset': {
            'field_length': 4,
            'field_offset': 512,
            'field_type': 4,
            'printable': '26240',
            'tag': 40965,
            'values': [26240]
        },
        'EXIF LightSource': {
            'field_length': 2,
            'field_offset': 368,
            'field_type': 3,
            'printable': 'Unknown',
            'tag': 37384,
            'values': [0]
        },
        'EXIF MaxApertureValue': {
            'field_length': 8,
            'field_offset': 772,
            'field_type': 5,
            'printable': '18/5',
            'tag': 37381,
            'values': [[18, 5]]
        },
        'EXIF MeteringMode': {
            'field_length': 2,
            'field_offset': 356,
            'field_type': 3,
            'printable': 'Pattern',
            'tag': 37383,
            'values': [5]
        },
        'EXIF Saturation': {
            'field_length': 2,
            'field_offset': 668,
            'field_type': 3,
            'printable': 'Normal',
            'tag': 41993,
            'values': [0]
        },
        'EXIF SceneCaptureType': {
            'field_length': 2,
            'field_offset': 632,
            'field_type': 3,
            'printable': 'Standard',
            'tag': 41990,
            'values': [0]
        },
        'EXIF SceneType': {
            'field_length': 1,
            'field_offset': 548,
            'field_type': 7,
            'printable': 'Directly Photographed',
            'tag': 41729,
            'values': [1]
        },
        'EXIF SensingMethod': {
            'field_length': 2,
            'field_offset': 524,
            'field_type': 3,
            'printable': 'One-chip color area',
            'tag': 41495,
            'values': [2]
        },
        'EXIF Sharpness': {
            'field_length': 2,
            'field_offset': 680,
            'field_type': 3,
            'printable': 'Normal',
            'tag': 41994,
            'values': [0]
        },
        'EXIF SubSecTime': {
            'field_length': 3,
            'field_offset': 428,
            'field_type': 2,
            'printable': '10',
            'tag': 37520,
            'values': '10'
        },
        'EXIF SubSecTimeDigitized': {
            'field_length': 3,
            'field_offset': 452,
            'field_type': 2,
            'printable': '10',
            'tag': 37522,
            'values': '10'
        },
        'EXIF SubSecTimeOriginal': {
            'field_length': 3,
            'field_offset': 440,
            'field_type': 2,
            'printable': '10',
            'tag': 37521,
            'values': '10'
        },
        'EXIF SubjectDistanceRange': {
            'field_length': 2,
            'field_offset': 692,
            'field_type': 3,
            'printable': '0',
            'tag': 41996,
            'values': [0]
        },
        'EXIF WhiteBalance': {
            'field_length': 2,
            'field_offset': 596,
            'field_type': 3,
            'printable': 'Auto',
            'tag': 41987,
            'values': [0]
        },
        'Image DateTime': {
            'field_length': 20,
            'field_offset': 194,
            'field_type': 2,
            'printable': '2011:06:22 12:20:33',
            'tag': 306,
            'values': '2011:06:22 12:20:33'
        },
        'Image ExifOffset': {
            'field_length': 4,
            'field_offset': 126,
            'field_type': 4,
            'printable': '214',
            'tag': 34665,
            'values': [214]
        },
        'Image Make': {
            'field_length': 18,
            'field_offset': 134,
            'field_type': 2,
            'printable': 'NIKON CORPORATION',
            'tag': 271,
            'values': 'NIKON CORPORATION'
        },
        'Image Model': {
            'field_length': 10,
            'field_offset': 152,
            'field_type': 2,
            'printable': 'NIKON D80',
            'tag': 272,
            'values': 'NIKON D80'
        },
        'Image Orientation': {
            'field_length': 2,
            'field_offset': 42,
            'field_type': 3,
            'printable': 'Rotated 90 CW',
            'tag': 274,
            'values': [6]
        },
        'Image ResolutionUnit': {
            'field_length': 2,
            'field_offset': 78,
            'field_type': 3,
            'printable': 'Pixels/Inch',
            'tag': 296,
            'values': [2]
        },
        'Image Software': {
            'field_length': 15,
            'field_offset': 178,
            'field_type': 2,
            'printable': 'Shotwell 0.9.3',
            'tag': 305,
            'values': 'Shotwell 0.9.3'
        },
        'Image XResolution': {
            'field_length': 8,
            'field_offset': 162,
            'field_type': 5,
            'printable': '300',
            'tag': 282,
            'values': [[300, 1]]
        },
        'Image YCbCrPositioning': {
            'field_length': 2,
            'field_offset': 114,
            'field_type': 3,
            'printable': 'Co-sited',
            'tag': 531,
            'values': [2]
        },
        'Image YResolution': {
            'field_length': 8,
            'field_offset': 170,
            'field_type': 5,
            'printable': '300',
            'tag': 283,
            'values': [[300, 1]]
        },
        'Thumbnail Compression': {
            'field_length': 2,
            'field_offset': 26280,
            'field_type': 3,
            'printable': 'JPEG (old-style)',
            'tag': 259,
            'values': [6]
        },
        'Thumbnail ResolutionUnit': {
            'field_length': 2,
            'field_offset': 26316,
            'field_type': 3,
            'printable': 'Pixels/Inch',
            'tag': 296,
            'values': [2]
        },
        'Thumbnail XResolution': {
            'field_length': 8,
            'field_offset': 26360,
            'field_type': 5,
            'printable': '300',
            'tag': 282,
            'values': [[300, 1]]
        },
        'Thumbnail YCbCrPositioning': {
            'field_length': 2,
            'field_offset': 26352,
            'field_type': 3,
            'printable': 'Co-sited',
            'tag': 531,
            'values': [2]
        },
        'Thumbnail YResolution': {
            'field_length': 8,
            'field_offset': 26368,
            'field_type': 5,
            'printable': '300',
            'tag': 283,
            'values': [[300, 1]]
        }
    })

    for key in expected.keys():
        assert useful[key] == expected[key]
Exemple #13
0
def process_image(entry):
    """
    Code to process an image
    """
    workbench = mgg.workbench_manager.create_workbench()
    # Conversions subdirectory to avoid collisions
    conversions_subdir = os.path.join(
        workbench.dir, 'conversions')
    os.mkdir(conversions_subdir)
    queued_filepath = entry.queued_media_file
    queued_filename = workbench.localized_file(
        mgg.queue_store, queued_filepath,
        'source')
    name_builder = FilenameBuilder(queued_filename)

    # EXIF extraction
    exif_tags = extract_exif(queued_filename)
    gps_data = get_gps_data(exif_tags)

    # Always create a small thumbnail
    thumb_filepath = create_pub_filepath(
        entry, name_builder.fill('{basename}.thumbnail{ext}'))
    resize_image(entry, queued_filename, thumb_filepath,
                exif_tags, conversions_subdir,
                (mgg.global_config['media:thumb']['max_width'],
                 mgg.global_config['media:thumb']['max_height']))

    # If the size of the original file exceeds the specified size of a `medium`
    # file, a `.medium.jpg` files is created and later associated with the media
    # entry.
    medium = Image.open(queued_filename)
    if medium.size[0] > mgg.global_config['media:medium']['max_width'] \
        or medium.size[1] > mgg.global_config['media:medium']['max_height'] \
        or exif_image_needs_rotation(exif_tags):
        medium_filepath = create_pub_filepath(
            entry, name_builder.fill('{basename}.medium{ext}'))
        resize_image(
            entry, queued_filename, medium_filepath,
            exif_tags, conversions_subdir,
            (mgg.global_config['media:medium']['max_width'],
             mgg.global_config['media:medium']['max_height']))
    else:
        medium_filepath = None

    # we have to re-read because unlike PIL, not everything reads
    # things in string representation :)
    queued_file = file(queued_filename, 'rb')

    with queued_file:
        original_filepath = create_pub_filepath(
            entry, name_builder.fill('{basename}{ext}'))

        with mgg.public_store.get_file(original_filepath, 'wb') \
            as original_file:
            original_file.write(queued_file.read())

    # Remove queued media file from storage and database
    mgg.queue_store.delete_file(queued_filepath)
    entry.queued_media_file = []

    # Insert media file information into database
    media_files_dict = entry.setdefault('media_files', {})
    media_files_dict[u'thumb'] = thumb_filepath
    media_files_dict[u'original'] = original_filepath
    if medium_filepath:
        media_files_dict[u'medium'] = medium_filepath

    # Insert exif data into database
    exif_all = clean_exif(exif_tags)

    if len(exif_all):
        entry.media_data_init(exif_all=exif_all)

    if len(gps_data):
        for key in list(gps_data.keys()):
            gps_data['gps_' + key] = gps_data.pop(key)
        entry.media_data_init(**gps_data)

    # clean up workbench
    workbench.destroy_self()
Exemple #14
0
    # Copy our queued local workbench to its final destination
    proc_state.copy_original(name_builder.fill('{basename}{ext}'))

    # Remove queued media file from storage and database
    proc_state.delete_queue_file()

    # Insert exif data into database
    exif_all = clean_exif(exif_tags)

    if len(exif_all):
        entry.media_data_init(exif_all=exif_all)

    if len(gps_data):
        for key in list(gps_data.keys()):
            gps_data['gps_' + key] = gps_data.pop(key)
        entry.media_data_init(**gps_data)


if __name__ == '__main__':
    import sys
    import pprint

    pp = pprint.PrettyPrinter()

    result = extract_exif(sys.argv[1])
    gps = get_gps_data(result)
    clean = clean_exif(result)
    useful = get_useful(clean)

    print pp.pprint(clean)
Exemple #15
0
def test_exif_extraction():
    """
    Test EXIF extraction from a good image
    """
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) == 55

    # Do we have clean data?
    assert len(clean) == 53

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?

    expected = OrderedDict(
        {
            "EXIF CVAPattern": {
                "field_length": 8,
                "field_offset": 26224,
                "field_type": 7,
                "printable": "[0, 2, 0, 2, 1, 2, 0, 1]",
                "tag": 41730,
                "values": [0, 2, 0, 2, 1, 2, 0, 1],
            },
            "EXIF ColorSpace": {
                "field_length": 2,
                "field_offset": 476,
                "field_type": 3,
                "printable": "sRGB",
                "tag": 40961,
                "values": [1],
            },
            "EXIF ComponentsConfiguration": {
                "field_length": 4,
                "field_offset": 308,
                "field_type": 7,
                "printable": "YCbCr",
                "tag": 37121,
                "values": [1, 2, 3, 0],
            },
            "EXIF CompressedBitsPerPixel": {
                "field_length": 8,
                "field_offset": 756,
                "field_type": 5,
                "printable": u"4",
                "tag": 37122,
                "values": [[4, 1]],
            },
            "EXIF Contrast": {
                "field_length": 2,
                "field_offset": 656,
                "field_type": 3,
                "printable": u"Soft",
                "tag": 41992,
                "values": [1],
            },
            "EXIF CustomRendered": {
                "field_length": 2,
                "field_offset": 572,
                "field_type": 3,
                "printable": u"Normal",
                "tag": 41985,
                "values": [0],
            },
            "EXIF DateTimeDigitized": {
                "field_length": 20,
                "field_offset": 736,
                "field_type": 2,
                "printable": u"2011:06:22 12:20:33",
                "tag": 36868,
                "values": u"2011:06:22 12:20:33",
            },
            "EXIF DateTimeOriginal": {
                "field_length": 20,
                "field_offset": 716,
                "field_type": 2,
                "printable": u"2011:06:22 12:20:33",
                "tag": 36867,
                "values": u"2011:06:22 12:20:33",
            },
            "EXIF DigitalZoomRatio": {
                "field_length": 8,
                "field_offset": 26232,
                "field_type": 5,
                "printable": u"1",
                "tag": 41988,
                "values": [[1, 1]],
            },
            "EXIF ExifImageLength": {
                "field_length": 2,
                "field_offset": 500,
                "field_type": 3,
                "printable": u"2592",
                "tag": 40963,
                "values": [2592],
            },
            "EXIF ExifImageWidth": {
                "field_length": 2,
                "field_offset": 488,
                "field_type": 3,
                "printable": u"3872",
                "tag": 40962,
                "values": [3872],
            },
            "EXIF ExifVersion": {
                "field_length": 4,
                "field_offset": 272,
                "field_type": 7,
                "printable": u"0221",
                "tag": 36864,
                "values": [48, 50, 50, 49],
            },
            "EXIF ExposureBiasValue": {
                "field_length": 8,
                "field_offset": 764,
                "field_type": 10,
                "printable": u"0",
                "tag": 37380,
                "values": [[0, 1]],
            },
            "EXIF ExposureMode": {
                "field_length": 2,
                "field_offset": 584,
                "field_type": 3,
                "printable": u"Manual Exposure",
                "tag": 41986,
                "values": [1],
            },
            "EXIF ExposureProgram": {
                "field_length": 2,
                "field_offset": 248,
                "field_type": 3,
                "printable": u"Manual",
                "tag": 34850,
                "values": [1],
            },
            "EXIF ExposureTime": {
                "field_length": 8,
                "field_offset": 700,
                "field_type": 5,
                "printable": u"1/125",
                "tag": 33434,
                "values": [[1, 125]],
            },
            "EXIF FNumber": {
                "field_length": 8,
                "field_offset": 708,
                "field_type": 5,
                "printable": u"10",
                "tag": 33437,
                "values": [[10, 1]],
            },
            "EXIF FileSource": {
                "field_length": 1,
                "field_offset": 536,
                "field_type": 7,
                "printable": u"Digital Camera",
                "tag": 41728,
                "values": [3],
            },
            "EXIF Flash": {
                "field_length": 2,
                "field_offset": 380,
                "field_type": 3,
                "printable": u"Flash did not fire",
                "tag": 37385,
                "values": [0],
            },
            "EXIF FlashPixVersion": {
                "field_length": 4,
                "field_offset": 464,
                "field_type": 7,
                "printable": u"0100",
                "tag": 40960,
                "values": [48, 49, 48, 48],
            },
            "EXIF FocalLength": {
                "field_length": 8,
                "field_offset": 780,
                "field_type": 5,
                "printable": u"18",
                "tag": 37386,
                "values": [[18, 1]],
            },
            "EXIF FocalLengthIn35mmFilm": {
                "field_length": 2,
                "field_offset": 620,
                "field_type": 3,
                "printable": u"27",
                "tag": 41989,
                "values": [27],
            },
            "EXIF GainControl": {
                "field_length": 2,
                "field_offset": 644,
                "field_type": 3,
                "printable": u"None",
                "tag": 41991,
                "values": [0],
            },
            "EXIF ISOSpeedRatings": {
                "field_length": 2,
                "field_offset": 260,
                "field_type": 3,
                "printable": u"100",
                "tag": 34855,
                "values": [100],
            },
            "EXIF InteroperabilityOffset": {
                "field_length": 4,
                "field_offset": 512,
                "field_type": 4,
                "printable": u"26240",
                "tag": 40965,
                "values": [26240],
            },
            "EXIF LightSource": {
                "field_length": 2,
                "field_offset": 368,
                "field_type": 3,
                "printable": u"Unknown",
                "tag": 37384,
                "values": [0],
            },
            "EXIF MaxApertureValue": {
                "field_length": 8,
                "field_offset": 772,
                "field_type": 5,
                "printable": u"18/5",
                "tag": 37381,
                "values": [[18, 5]],
            },
            "EXIF MeteringMode": {
                "field_length": 2,
                "field_offset": 356,
                "field_type": 3,
                "printable": u"Pattern",
                "tag": 37383,
                "values": [5],
            },
            "EXIF Saturation": {
                "field_length": 2,
                "field_offset": 668,
                "field_type": 3,
                "printable": u"Normal",
                "tag": 41993,
                "values": [0],
            },
            "EXIF SceneCaptureType": {
                "field_length": 2,
                "field_offset": 632,
                "field_type": 3,
                "printable": u"Standard",
                "tag": 41990,
                "values": [0],
            },
            "EXIF SceneType": {
                "field_length": 1,
                "field_offset": 548,
                "field_type": 7,
                "printable": u"Directly Photographed",
                "tag": 41729,
                "values": [1],
            },
            "EXIF SensingMethod": {
                "field_length": 2,
                "field_offset": 524,
                "field_type": 3,
                "printable": u"One-chip color area",
                "tag": 41495,
                "values": [2],
            },
            "EXIF Sharpness": {
                "field_length": 2,
                "field_offset": 680,
                "field_type": 3,
                "printable": u"Normal",
                "tag": 41994,
                "values": [0],
            },
            "EXIF SubSecTime": {
                "field_length": 3,
                "field_offset": 428,
                "field_type": 2,
                "printable": u"10",
                "tag": 37520,
                "values": u"10",
            },
            "EXIF SubSecTimeDigitized": {
                "field_length": 3,
                "field_offset": 452,
                "field_type": 2,
                "printable": u"10",
                "tag": 37522,
                "values": u"10",
            },
            "EXIF SubSecTimeOriginal": {
                "field_length": 3,
                "field_offset": 440,
                "field_type": 2,
                "printable": u"10",
                "tag": 37521,
                "values": u"10",
            },
            "EXIF SubjectDistanceRange": {
                "field_length": 2,
                "field_offset": 692,
                "field_type": 3,
                "printable": u"0",
                "tag": 41996,
                "values": [0],
            },
            "EXIF WhiteBalance": {
                "field_length": 2,
                "field_offset": 596,
                "field_type": 3,
                "printable": u"Auto",
                "tag": 41987,
                "values": [0],
            },
            "Image DateTime": {
                "field_length": 20,
                "field_offset": 194,
                "field_type": 2,
                "printable": u"2011:06:22 12:20:33",
                "tag": 306,
                "values": u"2011:06:22 12:20:33",
            },
            "Image ExifOffset": {
                "field_length": 4,
                "field_offset": 126,
                "field_type": 4,
                "printable": u"214",
                "tag": 34665,
                "values": [214],
            },
            "Image Make": {
                "field_length": 18,
                "field_offset": 134,
                "field_type": 2,
                "printable": u"NIKON CORPORATION",
                "tag": 271,
                "values": u"NIKON CORPORATION",
            },
            "Image Model": {
                "field_length": 10,
                "field_offset": 152,
                "field_type": 2,
                "printable": u"NIKON D80",
                "tag": 272,
                "values": u"NIKON D80",
            },
            "Image Orientation": {
                "field_length": 2,
                "field_offset": 42,
                "field_type": 3,
                "printable": u"Rotated 90 CCW",
                "tag": 274,
                "values": [6],
            },
            "Image ResolutionUnit": {
                "field_length": 2,
                "field_offset": 78,
                "field_type": 3,
                "printable": u"Pixels/Inch",
                "tag": 296,
                "values": [2],
            },
            "Image Software": {
                "field_length": 15,
                "field_offset": 178,
                "field_type": 2,
                "printable": u"Shotwell 0.9.3",
                "tag": 305,
                "values": u"Shotwell 0.9.3",
            },
            "Image XResolution": {
                "field_length": 8,
                "field_offset": 162,
                "field_type": 5,
                "printable": u"300",
                "tag": 282,
                "values": [[300, 1]],
            },
            "Image YCbCrPositioning": {
                "field_length": 2,
                "field_offset": 114,
                "field_type": 3,
                "printable": u"Co-sited",
                "tag": 531,
                "values": [2],
            },
            "Image YResolution": {
                "field_length": 8,
                "field_offset": 170,
                "field_type": 5,
                "printable": u"300",
                "tag": 283,
                "values": [[300, 1]],
            },
            "Thumbnail Compression": {
                "field_length": 2,
                "field_offset": 26280,
                "field_type": 3,
                "printable": u"JPEG (old-style)",
                "tag": 259,
                "values": [6],
            },
            "Thumbnail ResolutionUnit": {
                "field_length": 2,
                "field_offset": 26316,
                "field_type": 3,
                "printable": u"Pixels/Inch",
                "tag": 296,
                "values": [2],
            },
            "Thumbnail XResolution": {
                "field_length": 8,
                "field_offset": 26360,
                "field_type": 5,
                "printable": u"300",
                "tag": 282,
                "values": [[300, 1]],
            },
            "Thumbnail YCbCrPositioning": {
                "field_length": 2,
                "field_offset": 26352,
                "field_type": 3,
                "printable": u"Co-sited",
                "tag": 531,
                "values": [2],
            },
            "Thumbnail YResolution": {
                "field_length": 8,
                "field_offset": 26368,
                "field_type": 5,
                "printable": u"300",
                "tag": 283,
                "values": [[300, 1]],
            },
        }
    )

    for k, v in useful.items():
        assert v == expected[k]
Exemple #16
0
def test_exif_extraction():
    '''
    Test EXIF extraction from a good image
    '''
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) >= 50

    # Do we have clean data?
    assert len(clean) >= 50

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?

    expected = OrderedDict({'EXIF CVAPattern': {'field_length': 8,
                     'field_offset': 26224,
                     'field_type': 7,
                     'printable': '[0, 2, 0, 2, 1, 2, 0, 1]',
                     'tag': 41730,
                     'values': [0, 2, 0, 2, 1, 2, 0, 1]},
 'EXIF ColorSpace': {'field_length': 2,
                     'field_offset': 476,
                     'field_type': 3,
                     'printable': 'sRGB',
                     'tag': 40961,
                     'values': [1]},
 'EXIF ComponentsConfiguration': {'field_length': 4,
                                  'field_offset': 308,
                                  'field_type': 7,
                                  'printable': 'YCbCr',
                                  'tag': 37121,
                                  'values': [1, 2, 3, 0]},
 'EXIF CompressedBitsPerPixel': {'field_length': 8,
                                 'field_offset': 756,
                                 'field_type': 5,
                                 'printable': u'4',
                                 'tag': 37122,
                                 'values': [[4, 1]]},
 'EXIF Contrast': {'field_length': 2,
                   'field_offset': 656,
                   'field_type': 3,
                   'printable': u'Soft',
                   'tag': 41992,
                   'values': [1]},
 'EXIF CustomRendered': {'field_length': 2,
                         'field_offset': 572,
                         'field_type': 3,
                         'printable': u'Normal',
                         'tag': 41985,
                         'values': [0]},
 'EXIF DateTimeDigitized': {'field_length': 20,
                            'field_offset': 736,
                            'field_type': 2,
                            'printable': u'2011:06:22 12:20:33',
                            'tag': 36868,
                            'values': u'2011:06:22 12:20:33'},
 'EXIF DateTimeOriginal': {'field_length': 20,
                           'field_offset': 716,
                           'field_type': 2,
                           'printable': u'2011:06:22 12:20:33',
                           'tag': 36867,
                           'values': u'2011:06:22 12:20:33'},
 'EXIF DigitalZoomRatio': {'field_length': 8,
                           'field_offset': 26232,
                           'field_type': 5,
                           'printable': u'1',
                           'tag': 41988,
                           'values': [[1, 1]]},
 'EXIF ExifImageLength': {'field_length': 2,
                          'field_offset': 500,
                          'field_type': 3,
                          'printable': u'2592',
                          'tag': 40963,
                          'values': [2592]},
 'EXIF ExifImageWidth': {'field_length': 2,
                         'field_offset': 488,
                         'field_type': 3,
                         'printable': u'3872',
                         'tag': 40962,
                         'values': [3872]},
 'EXIF ExifVersion': {'field_length': 4,
                      'field_offset': 272,
                      'field_type': 7,
                      'printable': u'0221',
                      'tag': 36864,
                      'values': [48, 50, 50, 49]},
 'EXIF ExposureBiasValue': {'field_length': 8,
                            'field_offset': 764,
                            'field_type': 10,
                            'printable': u'0',
                            'tag': 37380,
                            'values': [[0, 1]]},
 'EXIF ExposureMode': {'field_length': 2,
                       'field_offset': 584,
                       'field_type': 3,
                       'printable': u'Manual Exposure',
                       'tag': 41986,
                       'values': [1]},
 'EXIF ExposureProgram': {'field_length': 2,
                          'field_offset': 248,
                          'field_type': 3,
                          'printable': u'Manual',
                          'tag': 34850,
                          'values': [1]},
 'EXIF ExposureTime': {'field_length': 8,
                       'field_offset': 700,
                       'field_type': 5,
                       'printable': u'1/125',
                       'tag': 33434,
                       'values': [[1, 125]]},
 'EXIF FNumber': {'field_length': 8,
                  'field_offset': 708,
                  'field_type': 5,
                  'printable': u'10',
                  'tag': 33437,
                  'values': [[10, 1]]},
 'EXIF FileSource': {'field_length': 1,
                     'field_offset': 536,
                     'field_type': 7,
                     'printable': u'Digital Camera',
                     'tag': 41728,
                     'values': [3]},
 'EXIF Flash': {'field_length': 2,
                'field_offset': 380,
                'field_type': 3,
                'printable': u'Flash did not fire',
                'tag': 37385,
                'values': [0]},
 'EXIF FlashPixVersion': {'field_length': 4,
                          'field_offset': 464,
                          'field_type': 7,
                          'printable': u'0100',
                          'tag': 40960,
                          'values': [48, 49, 48, 48]},
 'EXIF FocalLength': {'field_length': 8,
                      'field_offset': 780,
                      'field_type': 5,
                      'printable': u'18',
                      'tag': 37386,
                      'values': [[18, 1]]},
 'EXIF FocalLengthIn35mmFilm': {'field_length': 2,
                                'field_offset': 620,
                                'field_type': 3,
                                'printable': u'27',
                                'tag': 41989,
                                'values': [27]},
 'EXIF GainControl': {'field_length': 2,
                      'field_offset': 644,
                      'field_type': 3,
                      'printable': u'None',
                      'tag': 41991,
                      'values': [0]},
 'EXIF ISOSpeedRatings': {'field_length': 2,
                          'field_offset': 260,
                          'field_type': 3,
                          'printable': u'100',
                          'tag': 34855,
                          'values': [100]},
 'EXIF InteroperabilityOffset': {'field_length': 4,
                                 'field_offset': 512,
                                 'field_type': 4,
                                 'printable': u'26240',
                                 'tag': 40965,
                                 'values': [26240]},
 'EXIF LightSource': {'field_length': 2,
                      'field_offset': 368,
                      'field_type': 3,
                      'printable': u'Unknown',
                      'tag': 37384,
                      'values': [0]},
 'EXIF MaxApertureValue': {'field_length': 8,
                           'field_offset': 772,
                           'field_type': 5,
                           'printable': u'18/5',
                           'tag': 37381,
                           'values': [[18, 5]]},
 'EXIF MeteringMode': {'field_length': 2,
                       'field_offset': 356,
                       'field_type': 3,
                       'printable': u'Pattern',
                       'tag': 37383,
                       'values': [5]},
 'EXIF Saturation': {'field_length': 2,
                     'field_offset': 668,
                     'field_type': 3,
                     'printable': u'Normal',
                     'tag': 41993,
                     'values': [0]},
 'EXIF SceneCaptureType': {'field_length': 2,
                           'field_offset': 632,
                           'field_type': 3,
                           'printable': u'Standard',
                           'tag': 41990,
                           'values': [0]},
 'EXIF SceneType': {'field_length': 1,
                    'field_offset': 548,
                    'field_type': 7,
                    'printable': u'Directly Photographed',
                    'tag': 41729,
                    'values': [1]},
 'EXIF SensingMethod': {'field_length': 2,
                        'field_offset': 524,
                        'field_type': 3,
                        'printable': u'One-chip color area',
                        'tag': 41495,
                        'values': [2]},
 'EXIF Sharpness': {'field_length': 2,
                    'field_offset': 680,
                    'field_type': 3,
                    'printable': u'Normal',
                    'tag': 41994,
                    'values': [0]},
 'EXIF SubSecTime': {'field_length': 3,
                     'field_offset': 428,
                     'field_type': 2,
                     'printable': u'10',
                     'tag': 37520,
                     'values': u'10'},
 'EXIF SubSecTimeDigitized': {'field_length': 3,
                              'field_offset': 452,
                              'field_type': 2,
                              'printable': u'10',
                              'tag': 37522,
                              'values': u'10'},
 'EXIF SubSecTimeOriginal': {'field_length': 3,
                             'field_offset': 440,
                             'field_type': 2,
                             'printable': u'10',
                             'tag': 37521,
                             'values': u'10'},
 'EXIF SubjectDistanceRange': {'field_length': 2,
                               'field_offset': 692,
                               'field_type': 3,
                               'printable': u'0',
                               'tag': 41996,
                               'values': [0]},
 'EXIF WhiteBalance': {'field_length': 2,
                       'field_offset': 596,
                       'field_type': 3,
                       'printable': u'Auto',
                       'tag': 41987,
                       'values': [0]},
 'Image DateTime': {'field_length': 20,
                    'field_offset': 194,
                    'field_type': 2,
                    'printable': u'2011:06:22 12:20:33',
                    'tag': 306,
                    'values': u'2011:06:22 12:20:33'},
 'Image ExifOffset': {'field_length': 4,
                      'field_offset': 126,
                      'field_type': 4,
                      'printable': u'214',
                      'tag': 34665,
                      'values': [214]},
 'Image Make': {'field_length': 18,
                'field_offset': 134,
                'field_type': 2,
                'printable': u'NIKON CORPORATION',
                'tag': 271,
                'values': u'NIKON CORPORATION'},
 'Image Model': {'field_length': 10,
                 'field_offset': 152,
                 'field_type': 2,
                 'printable': u'NIKON D80',
                 'tag': 272,
                 'values': u'NIKON D80'},
 'Image Orientation': {'field_length': 2,
                       'field_offset': 42,
                       'field_type': 3,
                       'printable': u'Rotated 90 CCW',
                       'tag': 274,
                       'values': [6]},
 'Image ResolutionUnit': {'field_length': 2,
                          'field_offset': 78,
                          'field_type': 3,
                          'printable': u'Pixels/Inch',
                          'tag': 296,
                          'values': [2]},
 'Image Software': {'field_length': 15,
                    'field_offset': 178,
                    'field_type': 2,
                    'printable': u'Shotwell 0.9.3',
                    'tag': 305,
                    'values': u'Shotwell 0.9.3'},
 'Image XResolution': {'field_length': 8,
                       'field_offset': 162,
                       'field_type': 5,
                       'printable': u'300',
                       'tag': 282,
                       'values': [[300, 1]]},
 'Image YCbCrPositioning': {'field_length': 2,
                            'field_offset': 114,
                            'field_type': 3,
                            'printable': u'Co-sited',
                            'tag': 531,
                            'values': [2]},
 'Image YResolution': {'field_length': 8,
                       'field_offset': 170,
                       'field_type': 5,
                       'printable': u'300',
                       'tag': 283,
                       'values': [[300, 1]]},
 'Thumbnail Compression': {'field_length': 2,
                           'field_offset': 26280,
                           'field_type': 3,
                           'printable': u'JPEG (old-style)',
                           'tag': 259,
                           'values': [6]},
 'Thumbnail ResolutionUnit': {'field_length': 2,
                              'field_offset': 26316,
                              'field_type': 3,
                              'printable': u'Pixels/Inch',
                              'tag': 296,
                              'values': [2]},
 'Thumbnail XResolution': {'field_length': 8,
                           'field_offset': 26360,
                           'field_type': 5,
                           'printable': u'300',
                           'tag': 282,
                           'values': [[300, 1]]},
 'Thumbnail YCbCrPositioning': {'field_length': 2,
                                'field_offset': 26352,
                                'field_type': 3,
                                'printable': u'Co-sited',
                                'tag': 531,
                                'values': [2]},
 'Thumbnail YResolution': {'field_length': 8,
                           'field_offset': 26368,
                           'field_type': 5,
                           'printable': u'300',
                           'tag': 283,
                           'values': [[300, 1]]}})

    for key in expected.keys():
        assert useful[key] == expected[key]
Exemple #17
0
def test_exif_extraction():
    '''
    Test EXIF extraction from a good image
    '''
    result = extract_exif(GOOD_JPG)
    clean = clean_exif(result)
    useful = get_useful(clean)
    gps = get_gps_data(result)

    # Do we have the result?
    assert len(result) == 108

    # Do we have clean data?
    assert len(clean) == 105

    # GPS data?
    assert gps == {}

    # Do we have the "useful" tags?
    assert useful == {
        'EXIF Flash': {
            'field_type': 3,
            'printable': 'No',
            'field_offset': 380,
            'tag': 37385,
            'values': [0],
            'field_length': 2},
        'EXIF ExposureTime': {
            'field_type': 5,
            'printable': '1/125',
            'field_offset': 700,
            'tag': 33434,
            'values': [[1, 125]],
            'field_length': 8},
        'EXIF FocalLength': {
            'field_type': 5,
            'printable': '18',
            'field_offset': 780,
            'tag': 37386,
            'values': [[18, 1]],
            'field_length': 8},
        'Image Model': {
            'field_type': 2,
            'printable': 'NIKON D80',
            'field_offset': 152,
            'tag': 272,
            'values': 'NIKON D80',
            'field_length': 10},
        'Image Make': {
            'field_type': 2,
            'printable': 'NIKON CORPORATION',
            'field_offset': 134,
            'tag': 271,
            'values': 'NIKON CORPORATION',
            'field_length': 18},
        'EXIF ExposureMode': {
            'field_type': 3,
            'printable': 'Manual Exposure',
            'field_offset': 584,
            'tag': 41986,
            'values': [1],
            'field_length': 2},
        'EXIF ISOSpeedRatings': {
            'field_type': 3,
            'printable': '100',
            'field_offset': 260,
            'tag': 34855,
            'values': [100],
            'field_length': 2},
        'EXIF FNumber': {
            'field_type': 5,
            'printable': '10',
            'field_offset': 708,
            'tag': 33437,
            'values': [[10, 1]],
            'field_length': 8},
        'EXIF UserComment': {
            'field_type': 7,
            'printable': 'Joar Wandborg                       ',
            'field_offset': 26180,
            'tag': 37510,
            'values': [
                65, 83, 67, 73, 73, 0, 0, 0, 74, 111, 97, 114, 32, 87,
                97, 110, 100, 98, 111, 114, 103, 32, 32, 32, 32, 32, 32,
                32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
                32, 32, 32],
            'field_length': 44}}