{"id":13830884,"url":"https://github.com/tonytonyjan/exif","last_synced_at":"2025-04-04T20:11:02.126Z","repository":{"id":22611647,"uuid":"25953941","full_name":"tonytonyjan/exif","owner":"tonytonyjan","description":"The fastest Ruby EXIF reader.","archived":false,"fork":false,"pushed_at":"2023-08-25T06:25:19.000Z","size":493,"stargazers_count":148,"open_issues_count":8,"forks_count":20,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-04-09T21:30:09.724Z","etag":null,"topics":["exif","ruby"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tonytonyjan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2014-10-30T03:59:59.000Z","updated_at":"2024-01-17T12:19:15.000Z","dependencies_parsed_at":"2024-01-13T16:20:31.280Z","dependency_job_id":"d9db2a44-4d75-4906-aca6-6f7e1dc364dd","html_url":"https://github.com/tonytonyjan/exif","commit_stats":{"total_commits":132,"total_committers":5,"mean_commits":26.4,"dds":0.09848484848484851,"last_synced_commit":"1254e1e576bffb550f3bd20be9deb3d0f3edd939"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonytonyjan%2Fexif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonytonyjan%2Fexif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonytonyjan%2Fexif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tonytonyjan%2Fexif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tonytonyjan","download_url":"https://codeload.github.com/tonytonyjan/exif/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247242678,"owners_count":20907134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["exif","ruby"],"created_at":"2024-08-04T10:01:11.413Z","updated_at":"2025-04-04T20:11:02.109Z","avatar_url":"https://github.com/tonytonyjan.png","language":"C","readme":"A Ruby EXIF reader written in C. ![Build Status](https://github.com/tonytonyjan/exif/actions/workflows/ci.yml/badge.svg)\n\n# Installation\n\n    $ gem install exif\n\nPlease make sure you have installed `libexif`:\n\n    $ brew install libexif             # Homebrew\n    $ sudo apt-get install libexif-dev # APT\n    $ sudo yum install libexif-devel   # CentOS\n\n# Usage\n\n```ruby\ndata = Exif::Data.new(IO.read('sample.jpg'))   # load from string\ndata = Exif::Data.new(\"Exif\\x00\\x00II...\")     # load raw exif data\ndata = Exif::Data.new(File.open('sample.jpg')) # load from file\ndata.model         # =\u003e \"NIKON D600\"\ndata.image_width   # =\u003e 4000\ndata.gps_longitude # =\u003e [(121/1), (76869/2500), (0/1)]\ndata.date_time     # =\u003e \"2013:12:08 21:14:11\"\n\n# get all entries in an IFD\ndata[:ifd0]             # =\u003e {image_width: 4000, image_length: 2670, ...}\ndata[:ifd1]             # =\u003e {x_resolution: (72/1), y_resolution: (72/1), ...}\ndata[:exif]             # =\u003e exposure_time: (1/125), fnumber: (8/1)}\ndata[:gps]              # =\u003e {gps_version_id: [2, 2, 0, 0], gps_latitude_ref: \"N\", ...}\ndata[:interoperability] # =\u003e {...}\ndata.to_h               # =\u003e {:ifd0 =\u003e {...}, :ifd1 =\u003e {...}, :exif =\u003e {...}}\ndata.ifds == data.to_h  # =\u003e true\n```\n\n`ifd0` takes precedence over `ifd1`, since `ifd0` and `ifd1` share the same domain of tags, sometimes the same tag can be both used inside them, in this case, calling top-level API like `Exif::Data#image_width` will return the value of `ifd0`.\n\n# Typecasting\n\nTag Type  | Ruby Class\n----------|----------\nASCII     | String\nBYTE      | Integer\nDOUBLE    | Flat\nFLOAT     | Float\nLONG      | Integer\nRATIONAL  | Rational\nSHORT     | Integer\nUNDEFINED | String\n\n# How fast?\n\n**It's hundreds of times faster than mini_exiftool or exiftool and several times faster than exifr.**\n\nThere are similar excellent gems like [exifr](https://github.com/remvee/exifr), [mini_exiftool](https://github.com/janfri/mini_exiftool) and [exiftool](https://github.com/mceachen/exiftool.rb) built in pure Ruby while this one is a C extension.\n\nIf you are using JRuby you might want to give exifr, exiftool or mini_exiftool a look, the latter two are commandline wrappers for [ExifTool](http://www.sno.phy.queensu.ca/~phil/exiftool/) by Phil Harvey and support many file formats. The exiftool gem can process multiple files at once while mini_exiftool can modify or copy EXIF data.\n\n# Benchmark\n\nYou can find all benchmark files in [/benchmark](benchmark):\n\nRead a single tag from 100 files.\n```\n$ ruby benchmark/load_file.rb\nRehearsal ---------------------------------------------------------\nmini_exiftool (2.9.0)   0.240000   0.110000  22.830000 ( 23.275885)\nexiftool (1.2.0)        0.480000   0.130000  22.870000 ( 23.311755)\nexifr (1.3.2)           0.120000   0.010000   0.130000 (  0.139821)\nexif (49b6835)          0.020000   0.000000   0.020000 (  0.019927)\n----------------------------------------------- total: 45.850000sec\n\n                            user     system      total        real\nmini_exiftool (2.9.0)   0.240000   0.120000  22.830000 ( 23.267355)\nexiftool (1.2.0)        0.490000   0.130000  23.190000 ( 23.678799)\nexifr (1.3.2)           0.120000   0.010000   0.130000 (  0.134572)\nexif (49b6835)          0.020000   0.000000   0.020000 (  0.018419)\n-----------------------------------------\n1263 times faster than mini_exiftool (2.9.0)\n1286 times faster than exiftool (1.2.0)\n7 times faster than exifr (1.3.2)\n```\n\nRead many tags from the same file 1000 times.\n```\n$ ruby benchmark/read_tag.rb\nRehearsal ---------------------------------------------------------\nmini_exiftool (2.9.0)   0.390000   0.000000   0.390000 (  0.404067)\nexiftool (1.2.0)        0.030000   0.000000   0.030000 (  0.027073)\nexifr (1.3.2)           1.220000   0.020000   1.240000 (  1.268672)\nexif (49b6835)          0.010000   0.000000   0.010000 (  0.006862)\n------------------------------------------------ total: 1.670000sec\n\n                            user     system      total        real\nmini_exiftool (2.9.0)   0.410000   0.010000   0.420000 (  0.412627)\nexiftool (1.2.0)        0.030000   0.000000   0.030000 (  0.028518)\nexifr (1.3.2)           1.180000   0.010000   1.190000 (  1.203806)\nexif (49b6835)          0.010000   0.000000   0.010000 (  0.006925)\n-----------------------------------------\n60 times faster than mini_exiftool (2.9.0)\n4 times faster than exiftool (1.2.0)\n174 times faster than exifr (1.3.2)\n```\n\n# Contribution\n\n- Please follow [AngularJS git commit message conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#heading=h.uyo6cb12dt6w).\n\n# Tag Reference\n\n- aperture_value\n- artist\n- battery_level\n- bits_per_sample\n- body_serial_number\n- brightness_value\n- camera_owner_name\n- cfa_pattern\n- cfa_repeat_pattern_dim\n- color_space\n- components_configuration\n- composite_image\n- compressed_bits_per_pixel\n- compression\n- contrast\n- copyright\n- custom_rendered\n- date_time\n- date_time_digitized\n- date_time_original\n- device_setting_description\n- digital_zoom_ratio\n- document_name\n- exif_ifd_pointer\n- exif_version\n- exposure_bias_value\n- exposure_index\n- exposure_mode\n- exposure_program\n- exposure_time\n- file_source\n- fill_order\n- flash\n- flash_energy\n- flash_pix_version\n- fnumber\n- focal_length\n- focal_length_in_35mm_film\n- focal_plane_resolution_unit\n- focal_plane_x_resolution\n- focal_plane_y_resolution\n- gain_control\n- gamma\n- gps_altitude\n- gps_altitude_ref\n- gps_area_information\n- gps_date_stamp\n- gps_dest_bearing\n- gps_dest_bearing_ref\n- gps_dest_distance\n- gps_dest_distance_ref\n- gps_dest_latitude\n- gps_dest_latitude_ref\n- gps_dest_longitude\n- gps_dest_longitude_ref\n- gps_differential\n- gps_dop\n- gps_h_positioning_error\n- gps_img_direction\n- gps_img_direction_ref\n- gps_info_ifd_pointer\n- gps_latitude\n- gps_latitude_ref\n- gps_longitude\n- gps_longitude_ref\n- gps_map_datum\n- gps_measure_mode\n- gps_processing_method\n- gps_satellites\n- gps_speed\n- gps_speed_ref\n- gps_status\n- gps_time_stamp\n- gps_track\n- gps_track_ref\n- gps_version_id\n- image_depth\n- image_description\n- image_length\n- image_resources\n- image_unique_id\n- image_width\n- inter_color_profile\n- interoperability_ifd_pointer\n- interoperability_index\n- interoperability_version\n- iptc_naa\n- iso_speed\n- iso_speed_ratings\n- iso_speedlatitudeyyy\n- iso_speedlatitudezzz\n- jpeg_interchange_format\n- jpeg_interchange_format_length\n- jpeg_proc\n- lens_make\n- lens_model\n- lens_serial_number\n- lens_specification\n- light_source\n- make\n- maker_note\n- max_aperture_value\n- metering_mode\n- model\n- new_cfa_pattern\n- new_subfile_type\n- oecf\n- offset_time\n- offset_time_digitized\n- offset_time_original\n- orientation\n- padding\n- photometric_interpretation\n- pixel_x_dimension\n- pixel_y_dimension\n- planar_configuration\n- primary_chromaticities\n- print_image_matching\n- recommended_exposure_index\n- reference_black_white\n- related_image_file_format\n- related_image_length\n- related_image_width\n- related_sound_file\n- resolution_unit\n- rows_per_strip\n- samples_per_pixel\n- saturation\n- scene_capture_type\n- scene_type\n- sensing_method\n- sensitivity_type\n- sharpness\n- shutter_speed_value\n- software\n- source_exposure_times_of_composite_image\n- source_image_number_of_composite_image\n- spatial_frequency_response\n- spectral_sensitivity\n- standard_output_sensitivity\n- strip_byte_counts\n- strip_offsets\n- sub_ifds\n- sub_sec_time\n- sub_sec_time_digitized\n- sub_sec_time_original\n- subject_area\n- subject_distance\n- subject_distance_range\n- subject_location\n- tiff_ep_standard_id\n- time_zone_offset\n- transfer_function\n- transfer_range\n- user_comment\n- white_balance\n- white_point\n- x_resolution\n- xml_packet\n- xp_author\n- xp_comment\n- xp_keywords\n- xp_subject\n- xp_title\n- y_resolution\n- ycbcr_coefficients\n- ycbcr_positioning\n- ycbcr_sub_sampling\n\n# TODO\n\n1. Create, update and delete tags.\n","funding_links":[],"categories":["C","Utilities"],"sub_categories":["Metadata Removal"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonytonyjan%2Fexif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftonytonyjan%2Fexif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftonytonyjan%2Fexif/lists"}