Created
April 10, 2019 19:14
-
-
Save tmichel/aa89883e0a40b49ad527b27d8a1044cb to your computer and use it in GitHub Desktop.
Extract Exif info from an image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"bytes" | |
"encoding/binary" | |
"errors" | |
"io" | |
) | |
const ( | |
// JPEG APP1 marker | |
jpegAPP1 = 0xE1 | |
) | |
var ( | |
errNoExifHeader = errors.New("exif: exif header not found") | |
exifHeader = append([]byte("Exif"), 0x00, 0x00) | |
) | |
func extractExif(r io.Reader) ([]byte, error) { | |
br := bufio.NewReader(r) | |
for { | |
// Find APP1 marker | |
if _, err := br.ReadBytes(0xFF); err != nil { | |
return nil, err | |
} | |
marker, err := br.ReadByte() | |
if err != nil { | |
return nil, err | |
} | |
if marker != jpegAPP1 { | |
continue | |
} | |
// Extract section length | |
dataLenBytes := make([]byte, 2) | |
io.ReadFull(br, dataLenBytes) | |
dataLen := int64(binary.BigEndian.Uint16(dataLenBytes)) - 2 | |
if dataLen < int64(len(exifHeader)) { | |
return nil, errNoExifHeader | |
} | |
// Reconstruct APP1 section | |
var exif bytes.Buffer | |
exif.WriteByte(0xFF) | |
exif.WriteByte(jpegAPP1) | |
exif.Write(dataLenBytes) | |
_, err = io.CopyN(&exif, br, dataLen) | |
if err != nil { | |
return nil, err | |
} | |
// Check whether APP1 contains Exif or not | |
data := exif.Bytes()[4:] // 0xFF + marker + 2 bytes for length | |
headerBytes := data[:len(exifHeader)] | |
if !bytes.Equal(headerBytes, exifHeader) { | |
return nil, errNoExifHeader | |
} | |
return exif.Bytes(), nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment