iOS 16 supports AVIF and WebP (#242)

* iOS 16 supports AVIF and WebP

* iOS 17 should support WebP and AVIF too

* Determine image type by GetFileContentType
This commit is contained in:
Nova Kwok 2023-07-03 16:57:47 +08:00 committed by GitHub
parent 77584df0ea
commit eea4537f22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 8 deletions

View File

@ -3,7 +3,7 @@ package handler
import ( import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "os"
"webp_server_go/config" "webp_server_go/config"
"webp_server_go/encoder" "webp_server_go/encoder"
"webp_server_go/helper" "webp_server_go/helper"
@ -93,11 +93,10 @@ func Convert(c *fiber.Ctx) error {
} }
finalFilename := helper.FindSmallestFiles(availableFiles) finalFilename := helper.FindSmallestFiles(availableFiles)
if strings.HasSuffix(finalFilename, ".webp ") {
c.Set("Content-Type", "image/webp") buf, _ := os.ReadFile(finalFilename)
} else if strings.HasSuffix(finalFilename, ".avif") { contentType := helper.GetFileContentType(buf)
c.Set("Content-Type", "image/avif") c.Set("Content-Type", contentType)
}
c.Set("X-Compression-Rate", helper.GetCompressionRate(rawImageAbs, finalFilename)) c.Set("X-Compression-Rate", helper.GetCompressionRate(rawImageAbs, finalFilename))
return c.SendFile(finalFilename) return c.SendFile(finalFilename)

View File

@ -1,9 +1,8 @@
package helper package helper
import ( import (
"bytes"
"fmt" "fmt"
"github.com/cespare/xxhash"
"github.com/valyala/fasthttp"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -11,9 +10,35 @@ import (
"time" "time"
"webp_server_go/config" "webp_server_go/config"
"github.com/cespare/xxhash"
"github.com/h2non/filetype"
"github.com/valyala/fasthttp"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
func avifMatcher(buf []byte) bool {
// use hexdump on macOS to see the magic number
// 0000001c 66747970 61766966 00000000 61766966 6d696631 6d696166
magicHeader := []byte{
0x0, 0x0, 0x0, 0x1c,
0x66, 0x74, 0x79, 0x70,
0x61, 0x76, 0x69, 0x66,
0x0, 0x0, 0x0, 0x0,
0x61, 0x76, 0x69, 0x66,
0x6d, 0x69, 0x66, 0x31,
0x6d, 0x69, 0x61, 0x66,
}
return len(buf) > 1 && bytes.Equal(buf[:28], magicHeader) || strings.Contains(string(buf), "ftypavif")
}
func GetFileContentType(buffer []byte) string {
filetype.AddMatcher(filetype.NewType("avif", "image/avif"), avifMatcher)
kind, _ := filetype.Match(buffer)
return kind.MIME.Value
}
func FileCount(dir string) int64 { func FileCount(dir string) int64 {
var count int64 = 0 var count int64 = 0
_ = filepath.Walk(dir, _ = filepath.Walk(dir,
@ -144,10 +169,18 @@ func GuessSupportedFormat(header *fasthttp.RequestHeader) []string {
// chrome on iOS will not send valid image accept header // chrome on iOS will not send valid image accept header
if strings.Contains(ua, "iPhone OS 14") || strings.Contains(ua, "CPU OS 14") || if strings.Contains(ua, "iPhone OS 14") || strings.Contains(ua, "CPU OS 14") ||
strings.Contains(ua, "iPhone OS 15") || strings.Contains(ua, "CPU OS 15") || strings.Contains(ua, "iPhone OS 15") || strings.Contains(ua, "CPU OS 15") ||
strings.Contains(ua, "iPhone OS 16") || strings.Contains(ua, "CPU OS 16") ||
strings.Contains(ua, "iPhone OS 17") || strings.Contains(ua, "CPU OS 17") ||
strings.Contains(ua, "Android") || strings.Contains(ua, "Linux") { strings.Contains(ua, "Android") || strings.Contains(ua, "Linux") {
supported["webp"] = true supported["webp"] = true
} }
// iOS 16 supports AVIF
if strings.Contains(ua, "iPhone OS 16") || strings.Contains(ua, "CPU OS 16") ||
strings.Contains(ua, "iPhone OS 17") || strings.Contains(ua, "CPU OS 17") {
supported["avif"] = true
}
// save true value's key to slice // save true value's key to slice
var accepted []string var accepted []string
for k, v := range supported { for k, v := range supported {