{"id":13399678,"url":"https://github.com/dsoprea/go-exif","last_synced_at":"2025-05-15T03:07:00.867Z","repository":{"id":39543987,"uuid":"129685185","full_name":"dsoprea/go-exif","owner":"dsoprea","description":"A very complete, highly tested, standards-driven (but customizable) EXIF reader/writer lovingly written in Go.","archived":false,"fork":false,"pushed_at":"2024-04-04T22:50:05.000Z","size":10340,"stargazers_count":537,"open_issues_count":16,"forks_count":70,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-14T03:07:32.369Z","etag":null,"topics":["exif","go","image-processing"],"latest_commit_sha":null,"homepage":"","language":"Go","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/dsoprea.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-16T04:34:54.000Z","updated_at":"2025-04-10T17:31:56.000Z","dependencies_parsed_at":"2024-06-18T12:37:27.296Z","dependency_job_id":null,"html_url":"https://github.com/dsoprea/go-exif","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-exif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-exif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-exif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dsoprea%2Fgo-exif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dsoprea","download_url":"https://codeload.github.com/dsoprea/go-exif/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254264766,"owners_count":22041793,"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","go","image-processing"],"created_at":"2024-07-30T19:00:41.305Z","updated_at":"2025-05-15T03:06:55.845Z","avatar_url":"https://github.com/dsoprea.png","language":"Go","funding_links":[],"categories":["Metadata Removal Tools","Utilities"],"sub_categories":["Notable Mentions","Metadata Removal"],"readme":"[![Build Status](https://app.travis-ci.com/dsoprea/go-exif.svg?branch=master)](https://app.travis-ci.com/dsoprea/go-exif)\n[![codecov](https://codecov.io/gh/dsoprea/go-exif/branch/master/graph/badge.svg)](https://codecov.io/gh/dsoprea/go-exif)\n[![Go Report Card](https://goreportcard.com/badge/github.com/dsoprea/go-exif/v3)](https://goreportcard.com/report/github.com/dsoprea/go-exif/v3)\n[![GoDoc](https://godoc.org/github.com/dsoprea/go-exif/v3?status.svg)](https://godoc.org/github.com/dsoprea/go-exif/v3)\n\n# Overview\n\nThis package provides native Go functionality to parse an existing EXIF block, update an existing EXIF block, or add a new EXIF block.\n\n\n# Getting\n\nTo get the project and dependencies:\n\n```\n$ git clone https://github.com/dsoprea/go-exif.git\n$ cd v3\n```\n\n\n# Requirements\n\n- Go \u003e= 1.17: Due to a breakage with \"go test\", we only officially support 1.17 for testing/CI reasons. It may still work in earlier versions if such a need is critically required, however.\n\n\n# Scope\n\nThis project is concerned only with parsing and encoding raw EXIF data. It does\nnot understand specific file-formats. This package assumes you know how to\nextract the raw EXIF data from a file, such as a JPEG, and, if you want to\nupdate it, know how to write it back. File-specific formats are not the concern\nof *go-exif*, though we provide\n[exif.SearchAndExtractExif][search-and-extract-exif] and\n[exif.SearchFileAndExtractExif][search-file-and-extract-exif] as brute-force\nsearch mechanisms that will help you explore the EXIF information for newer\nformats that you might not yet have any way to parse.\n\nThat said, the author also provides the following projects to support the\nefficient processing of the corresponding image formats:\n\n- [go-jpeg-image-structure](https://github.com/dsoprea/go-jpeg-image-structure)\n- [go-png-image-structure](https://github.com/dsoprea/go-png-image-structure)\n- [go-tiff-image-structure](https://github.com/dsoprea/go-tiff-image-structure)\n- [go-heic-exif-extractor](https://github.com/dsoprea/go-heic-exif-extractor)\n\nSee the [SetExif example in go-jpeg-image-structure][jpeg-set-exif] for\npractical information on getting started with JPEG files.\n\n\n# Usage\n\nThe package provides a set of [working examples][examples] and is covered by\nunit-tests. Please look to these for getting familiar with how to read and write\nEXIF.\n\nCreate an instance of the `Exif` type and call `Scan()` with a byte-slice, where\nthe first byte is the beginning of the raw EXIF data. You may pass a callback\nthat will be invoked for every tag or `nil` if you do not want one. If no\ncallback is given, you are effectively just validating the structure or parsing\nof the image.\n\nObviously, it is most efficient to properly parse the media file and then\nprovide the specific EXIF data to be parsed, but there is also a heuristic for\nfinding the EXIF data within the media blob, directly. This means that, at least\nfor testing or curiosity, **you do not have to parse or even understand the\nformat of image or audio file in order to find and decode the EXIF information\ninside of it.** See the usage of the `SearchAndExtractExif` method in the\nexample.\n\nThe library often refers to an IFD with an \"IFD path\" (e.g. IFD/Exif,\nIFD/GPSInfo). A \"fully-qualified\" IFD-path is one that includes an index\ndescribing which specific sibling IFD is being referred to if not the first one\n(e.g. IFD1, the IFD where the thumbnail is expressed per the TIFF standard).\n\nThere is an \"IFD mapping\" and a \"tag index\" that must be created and passed to\nthe library from the top. These contain all of the knowledge of the IFD\nhierarchies and their tag-IDs (the IFD mapping) and the tags that they are\nallowed to host (the tag index). There are convenience functions to load them\nwith the standard TIFF information, but you, alternatively, may choose\nsomething totally different (to support parsing any kind of EXIF data that does\nnot follow or is not relevant to TIFF at all).\n\n\n# Standards and Customization\n\nThis project is configuration driven. By default, it has no knowledge of tags\nand IDs until you load them prior to using (which is incorporated in the\nexamples). You are just as easily able to add additional custom IFDs and custom\ntags for them. If desired, you could completely ignore the standard information\nand load *totally* non-standard IFDs and tags.\n\nThis would be useful for divergent implementations that add non-standard\ninformation to images. It would also be useful if there is some need to just\nstore a flat list of tags in an image for simplified, proprietary usage.\n\n\n# Reader Tool\n\nThere is a runnable reading/dumping tool included:\n\n```\n$ go install github.com/dsoprea/go-exif/v3/command/exif-read-tool@latest\n$ exif-read-tool --filepath \"\u003cmedia file-path\u003e\"\n```\n\nExample output:\n\n```\nIFD-PATH=[IFD] ID=(0x010f) NAME=[Make] COUNT=(6) TYPE=[ASCII] VALUE=[Canon]\nIFD-PATH=[IFD] ID=(0x0110) NAME=[Model] COUNT=(22) TYPE=[ASCII] VALUE=[Canon EOS 5D Mark III]\nIFD-PATH=[IFD] ID=(0x0112) NAME=[Orientation] COUNT=(1) TYPE=[SHORT] VALUE=[1]\nIFD-PATH=[IFD] ID=(0x011a) NAME=[XResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]\nIFD-PATH=[IFD] ID=(0x011b) NAME=[YResolution] COUNT=(1) TYPE=[RATIONAL] VALUE=[72/1]\nIFD-PATH=[IFD] ID=(0x0128) NAME=[ResolutionUnit] COUNT=(1) TYPE=[SHORT] VALUE=[2]\nIFD-PATH=[IFD] ID=(0x0132) NAME=[DateTime] COUNT=(20) TYPE=[ASCII] VALUE=[2017:12:02 08:18:50]\n...\n```\n\nYou can also print the raw, parsed data as JSON:\n\n```\n$ exif-read-tool --filepath \"\u003cmedia file-path\u003e\" -json\n```\n\nExample output:\n\n```\n[\n    {\n        \"ifd_path\": \"IFD\",\n        \"fq_ifd_path\": \"IFD\",\n        \"ifd_index\": 0,\n        \"tag_id\": 271,\n        \"tag_name\": \"Make\",\n        \"tag_type_id\": 2,\n        \"tag_type_name\": \"ASCII\",\n        \"unit_count\": 6,\n        \"value\": \"Canon\",\n        \"value_string\": \"Canon\"\n    },\n    {\n        \"ifd_path\": \"IFD\",\n...\n```\n\n\n# Testing\n\nThe traditional method:\n\n```\n$ go test github.com/dsoprea/go-exif/v3/...\n```\n\n\n# Release Notes\n\n## v3 Release\n\nThis release primarily introduces an interchangeable data-layer, where any\n`io.ReadSeeker` can be used to read EXIF data rather than necessarily loading\nthe EXIF blob into memory first.\n\nSeveral backwards-incompatible clean-ups were also included in this release. See\n[releases][releases] for more information.\n\n## v2 Release\n\nFeatures a heavily reflowed interface that makes usage much simpler. The\nundefined-type tag-processing (which affects most photographic images) has also\nbeen overhauled and streamlined. It is now complete and stable. Adoption is\nstrongly encouraged.\n\n\n# *Contributing*\n\nEXIF has an excellently-documented structure but there are a lot of devices and\nmanufacturers out there. There are only so many files that we can personally\nfind to test against, and most of these are images that have been generated only\nin the past few years. JPEG, being the largest implementor of EXIF, has been\naround for even longer (but not much). Therefore, there is a lot of\ncompatibility to test for.\n\n**If you are able to help by running the included reader-tool against all of the\nEXIF-compatible files you have, it would be deeply appreciated. This is mostly\ngoing to be JPEG files (but not all variations). If you are able to test a large\nnumber of files (thousands or millions) then please post an issue mentioning how\nmany files you have processed. If you had failures, then please share them and\ntry to support efforts to understand them.**\n\nIf you are able to test 100K+ files, I will give you credit on the project. The\nfurther back in time your images reach, the higher in the list your name/company\nwill go.\n\n\n# Contributors/Testing\n\nThank you to the following users for solving non-trivial issues, supporting the\nproject with solving edge-case problems in specific images, or otherwise\nproviding their non-trivial time or image corpus to test go-exif:\n\n- [philip-firstorder](https://github.com/philip-firstorder) (200K images)\n- [matchstick](https://github.com/matchstick) (102K images)\n\nIn addition to these, it has been tested on my own collection, north of 560K\nimages.\n\n[search-and-extract-exif]: https://godoc.org/github.com/dsoprea/go-exif/v3#SearchAndExtractExif\n[search-file-and-extract-exif]: https://godoc.org/github.com/dsoprea/go-exif/v3#SearchFileAndExtractExif\n[jpeg-set-exif]: https://godoc.org/github.com/dsoprea/go-jpeg-image-structure#example-SegmentList-SetExif\n[examples]: https://godoc.org/github.com/dsoprea/go-exif/v3#pkg-examples\n[releases]: https://github.com/dsoprea/go-exif/releases\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsoprea%2Fgo-exif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdsoprea%2Fgo-exif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdsoprea%2Fgo-exif/lists"}