How to Check if a File is a Valid Image in Go
Created
Modified
Using DetectContentType Function
The http.DetectContentType()
function implements the algorithm described at https://mimesniff.spec.whatwg.org/ to determine the Content-Type of the given data. It considers at most the first 512 bytes of data. DetectContentType always returns a valid MIME type: if it cannot determine a more specific one, it returns "application/octet-stream".
The following example should cover whatever you are trying to do:
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
f, _ := os.Open("icon.png")
defer f.Close()
buff := make([]byte, 512)
if _, err := f.Read(buff); err != nil {
// panic()
fmt.Println(err)
}
s := http.DetectContentType(buff)
fmt.Println(s)
}
image/png
Using Magic Number
What is usually done is checking if the file has the right magic number for the image file format you want. While this test is not super accurate, it is usually good enough.
package main
import (
"fmt"
"os"
"strings"
)
var magicTable = map[string]string{
"\xff\xd8\xff": "image/jpeg",
"\x89PNG\r\n\x1a\n": "image/png",
"GIF87a": "image/gif",
"GIF89a": "image/gif",
}
func DetectType(b []byte) string {
s := string(b)
for key, val := range magicTable {
if strings.HasPrefix(s, key) {
return val
}
}
return ""
}
func main() {
f, _ := os.Open("icon.png")
defer f.Close()
buff := make([]byte, 512)
if _, err := f.Read(buff); err != nil {
// panic()
fmt.Println(err)
}
s := DetectType(buff)
fmt.Println(s)
}
image/png
Matching an image type pattern
An image MIME type is a MIME type whose type is "image".
Byte Pattern | Image MIME Type |
---|---|
00 00 01 00 | image/x-icon |
00 00 02 00 | image/x-icon |
42 4D | image/x-icon |
47 49 46 38 37 61 | image/gif |
47 49 46 38 39 61 | image/gif |
52 49 46 46 00 00 00 00 57 45 42 50 56 50 | image/webp |
89 50 4E 47 0D 0A 1A 0A | image/png |
FF D8 FF | image/jpeg |