init
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,3 +21,4 @@
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
data/
|
||||
|
99
bin/main.go
Normal file
99
bin/main.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/gif"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/chai2010/webp"
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
// 实现一个 web api 服务(获取指定尺寸的图片)
|
||||
func main() {
|
||||
|
||||
http.HandleFunc("/img/", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// URL 格式: /img/{id}-{version}@{倍图}{宽度}.{格式}
|
||||
reg := regexp.MustCompile(`^/img/([0-9a-zA-Z]+)-([0-9a-zA-Z]+)@([0-9]{1,4})x([0-9]{1,4}).(jpg|jpeg|png|webp)$`)
|
||||
matches := reg.FindStringSubmatch(r.URL.Path)
|
||||
if len(matches) != 6 {
|
||||
log.Println("URL 格式错误", matches)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 正则表达式获取参数
|
||||
id, version, multiple_str, width_str, format := matches[1], matches[2], matches[3], matches[4], matches[5]
|
||||
multiple, err := strconv.Atoi(multiple_str)
|
||||
if err != nil {
|
||||
log.Println("倍图参数错误", multiple_str)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
width, err := strconv.Atoi(width_str)
|
||||
if err != nil {
|
||||
log.Println("宽度参数错误", width_str)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println(id, version, multiple, width, format)
|
||||
|
||||
// 打開輸入文件
|
||||
file, err := os.Open("data/test.gif")
|
||||
if err != nil {
|
||||
log.Println("打开文件失败", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 將輸入文件解碼為 image.Image
|
||||
img, ext, err := image.Decode(file)
|
||||
if err != nil {
|
||||
log.Println("解码图像失败", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 如果是 GIF 格式的动态图片,直接返回
|
||||
if ext == "gif" {
|
||||
giffile, err := os.Open("data/test.gif")
|
||||
if err != nil {
|
||||
log.Println("打开文件失败", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
defer giffile.Close()
|
||||
gifimg, err := gif.DecodeAll(giffile)
|
||||
if err != nil {
|
||||
log.Println("解码图像失败", err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
gif.EncodeAll(w, gifimg)
|
||||
return
|
||||
}
|
||||
|
||||
// 將圖像轉換為 RGBA 格式(如果尚未採用該格式)
|
||||
if _, ok := img.(*image.RGBA); !ok {
|
||||
img = imaging.Clone(img)
|
||||
}
|
||||
|
||||
// 將圖像調整為指定宽度的 WebP 格式並將其寫入輸出到瀏覽器(高度自适应)
|
||||
if err = webp.Encode(w, imaging.Resize(img, multiple*width, 0, imaging.Lanczos), &webp.Options{Quality: 80}); err != nil {
|
||||
log.Println("编码图像失败", err.Error())
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
})
|
||||
log.Println("Server is running at http://localhost:6001")
|
||||
http.ListenAndServe(":6001", nil)
|
||||
}
|
12
go.mod
Normal file
12
go.mod
Normal file
@@ -0,0 +1,12 @@
|
||||
module git.satori.love/gameui/webp
|
||||
|
||||
go 1.18
|
||||
|
||||
require github.com/disintegration/imaging v1.6.2
|
||||
|
||||
require github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 // indirect
|
||||
|
||||
require (
|
||||
github.com/chai2010/webp v1.1.1
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect
|
||||
)
|
13
go.sum
Normal file
13
go.sum
Normal file
@@ -0,0 +1,13 @@
|
||||
github.com/chai2010/webp v1.1.1 h1:jTRmEccAJ4MGrhFOrPMpNGIJ/eybIgwKpcACsrTEapk=
|
||||
github.com/chai2010/webp v1.1.1/go.mod h1:0XVwvZWdjjdxpUEIf7b9g9VkHFnInUSYujwqTLEuldU=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 h1:A7o8tOERTtpD/poS+2VoassCjXpjHn916luXbf5QKD0=
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882/go.mod h1:5IwJoz9Pw7JsrCN4/skkxUtSWT7myuUPLhCgv6Q5vvQ=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
89
webp.go
Normal file
89
webp.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package webp
|
||||
|
||||
import (
|
||||
"image"
|
||||
"os"
|
||||
|
||||
"github.com/chai2010/webp"
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
// EncodeFile encodes the specified image file to WebP format with the given width and height.
|
||||
// The output file name is constructed by adding the .webp extension to the input file name.
|
||||
func EncodeFile(filename string, width, height int) error {
|
||||
// Open the input file
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// Decode the input file into an image.Image
|
||||
img, format, err := image.Decode(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert the image to RGBA format if it's not already in that format
|
||||
if _, ok := img.(*image.RGBA); !ok {
|
||||
img = imaging.Clone(img)
|
||||
}
|
||||
|
||||
// Resize the image to the specified dimensions
|
||||
resizedImg := imaging.Resize(img, width, height, imaging.Lanczos)
|
||||
|
||||
// Create a new file for writing the output
|
||||
outFilename := filename[:len(filename)-len(format)] + "webp"
|
||||
outFile, err := os.Create(outFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
// Encode the resized image to WebP format and write it to the output file
|
||||
err = webp.Encode(outFile, resizedImg, &webp.Options{Quality: 80})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//// Encode encodes the specified image to WebP format with the given width and height.
|
||||
//// The output data is returned as a byte slice.
|
||||
//func Encode(data []byte, width, height int) ([]byte, error) {
|
||||
// // Decode the input data into an image.Image
|
||||
// img, format, err := image.Decode(ioutil.NopCloser(bytes.NewReader(data)))
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// // Convert the image to RGBA format if it's not already in that format
|
||||
// if _, ok := img.(*image.RGBA); !ok {
|
||||
// img = imaging.Clone(img)
|
||||
// }
|
||||
//
|
||||
// // Resize the image to the specified dimensions
|
||||
// resizedImg := imaging.Resize(img, width, height, imaging.Lanczos)
|
||||
//
|
||||
// // Encode the resized image to WebP format and return it as a byte slice
|
||||
// var buf bytes.Buffer
|
||||
// err = webp.Encode(&buf, resizedImg, &webp.Options{Quality: 80})
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
//
|
||||
// return buf.Bytes(), nil
|
||||
//}
|
||||
//
|
||||
//// Decode decodes the specified WebP data into an image.Image.
|
||||
//func Decode(data []byte) (image.Image, error) {
|
||||
// return webp.Decode(bytes.NewReader(data))
|
||||
//}
|
||||
//
|
||||
//// IsWebP returns true if the specified data is a WebP image.
|
||||
//func IsWebP(data []byte) bool {
|
||||
// return webp.IsWebP(data)
|
||||
//}
|
||||
//
|
||||
//// IsPNG returns true if the specified
|
Reference in New Issue
Block a user