Exif
可交换图像文件格式(英语:Exchangeable image file format,官方简称Exif),是专门为数码相机的照片设定的文件格式,可以记录数码照片的属性信息和拍摄数据。
通过手机或者相机拍摄的照片中会携带Exif信息,而某些手机默认会携带地理位置等隐私信息,比如下面这张图片
它的Exif信息为:
可以直接看到该照片使用Redmi K30 Pro拍摄于2021:01:25 19:15:28,甚至还可以直接看到经纬度信息(手机设置中可关闭)。这种未经过处理的照片直接上传到网上之后,可能会造成隐私的泄露。
Go读取Exif信息
通过包goexif/exif,可以查看照片的全部Exif信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func GetExif() error { ImgFile := "./IMG_20210125_191526.jpg" file, err := os.Open(ImgFile) if err != nil { fmt.Println(err) return err } defer file.Close() x, err := exif.Decode(file) if err != nil { return err } fmt.Printf("%+v", x) return nil }
|
因为没找到直接操作图片Exif的库(如果有欢迎留言告诉我),只能通过解析图片的色彩空间,然后通过此色彩空间重新生成一张新的图片因为是重新生成的图片,也就相当于抹除了Exif信息
1 2 3 4 5 6 7 8 9 10 11 12 13
| func CreateNewImage(f, newF *os.File) error { m, _, err := image.Decode(f) if err != nil { return err } width, height := m.Bounds().Max.X, m.Bounds().Max.Y var subImage image.Image img := m.(*image.YCbCr) subImage = img.SubImage(image.Rect(0, 0, width, height)).(*image.YCbCr) err = jpeg.Encode(newF, subImage, &jpeg.Options{100}) return err }
|
所有代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package main
import ( "fmt" "image" _ "image/gif" "image/jpeg" _ "image/jpeg" _ "image/png" "os" "path" "strings"
"github.com/rwcarlsen/goexif/exif" )
func main() { ImgFile := "./IMG_20210125_191526.jpg" fileNameWithSuffix := path.Base(ImgFile) imgType := path.Ext(fileNameWithSuffix) fileNameOnly := strings.TrimSuffix(fileNameWithSuffix, imgType) newImageFile := fileNameOnly + "_no_exif" + imgType file, err := os.Open(ImgFile) if err != nil { fmt.Println("打开文件失败") return } defer file.Close() err = GetExif(file) if err != nil { panic(err) } file.Seek(0, 0) newFile, err := os.Create(newImageFile) if err != nil { fmt.Println("file create fail") panic(err) } defer newFile.Close() err = CreateNewImage(file, newFile) if err != nil { panic(err) } }
func GetExif(file *os.File) error { x, err := exif.Decode(file) if err != nil { return err } fmt.Printf("%+v", x)
return nil }
func CreateNewImage(f, newF *os.File) error { m, _, err := image.Decode(f) if err != nil { return err } width, height := m.Bounds().Max.X, m.Bounds().Max.Y var subImage image.Image img := m.(*image.YCbCr) subImage = img.SubImage(image.Rect(0, 0, width, height)).(*image.YCbCr) err = jpeg.Encode(newF, subImage, &jpeg.Options{100}) return err }
func Create(fileName string) (*os.File, error) { f, err := os.Create(fileName) if err != nil { fmt.Println("file create fail") return nil, err } return f, nil }
|