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

Related Tags

#check# #image#