DEBUG
This commit is contained in:
		
							
								
								
									
										157
									
								
								bin/main.go
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								bin/main.go
									
									
									
									
									
								
							@@ -1,20 +1,15 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"image"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"git.satori.love/gameui/webp/models"
 | 
			
		||||
	"github.com/chai2010/webp"
 | 
			
		||||
	"github.com/disintegration/imaging"
 | 
			
		||||
	_ "github.com/go-sql-driver/mysql"
 | 
			
		||||
	giftowebp "github.com/sizeofint/gif-to-webp"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
@@ -39,64 +34,30 @@ func main() {
 | 
			
		||||
	var mysqlConnection models.MysqlConnection
 | 
			
		||||
	mysqlConnection.Init()
 | 
			
		||||
 | 
			
		||||
	// URL 格式: /img/{type}/{id}.{format}?width=320&height=320&fit=cover
 | 
			
		||||
	http.HandleFunc("/img/", func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		log.Println(r.Method, r.URL.Path)
 | 
			
		||||
		// URL 格式: /img/{type}/{id}.{format}?width=320&height=320&fit=cover
 | 
			
		||||
		reg := regexp.MustCompile(`^/img/([0-9a-zA-Z]+)/([0-9a-zA-Z]+).(jpg|jpeg|png|webp)$`)
 | 
			
		||||
		matches := reg.FindStringSubmatch(r.URL.Path)
 | 
			
		||||
		if len(matches) != 5 {
 | 
			
		||||
		if len(matches) != 4 {
 | 
			
		||||
			log.Println("URL 格式错误", matches)
 | 
			
		||||
			w.WriteHeader(http.StatusNotFound)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		group, id, format, width, height, fit := matches[1], matches[2], matches[3], stringToInt(r.URL.Query().Get("width"), 0), stringToInt(r.URL.Query().Get("height"), 0), r.URL.Query().Get("fit")
 | 
			
		||||
		content, err := mysqlConnection.GetImageContent(group, id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("获取图片失败", format, err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var img models.Image
 | 
			
		||||
		img.Init(content)
 | 
			
		||||
 | 
			
		||||
		data, err := img.ToWebP(width, height, fit)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("转换图片失败", err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		w.Header().Set("Content-Type", "image/webp")
 | 
			
		||||
		w.Header().Set("Cache-Control", "max-age=31536000")
 | 
			
		||||
		w.Write(data)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// 直接走 CDN 的请求不缓存本地, 因此直接使用参数
 | 
			
		||||
	http.HandleFunc("/webp/", func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		log.Println(r.Method, r.URL.Path)
 | 
			
		||||
		// URL 格式: /img/{id}.{格式}?width=320&height=320&fit=cover
 | 
			
		||||
		reg := regexp.MustCompile(`^/webp/([0-9a-zA-Z]+).(jpg|jpeg|png|webp)$`)
 | 
			
		||||
		matches := reg.FindStringSubmatch(r.URL.Path)
 | 
			
		||||
		if len(matches) != 3 {
 | 
			
		||||
			log.Println("URL 格式错误", matches)
 | 
			
		||||
			w.WriteHeader(http.StatusNotFound)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		id, format, width, height, fit := matches[1], matches[2], stringToInt(r.URL.Query().Get("width"), 0), stringToInt(r.URL.Query().Get("height"), 0), r.URL.Query().Get("fit")
 | 
			
		||||
		content, err := mysqlConnection.GetImageContent(id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("获取图片失败", format, err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var img models.Image
 | 
			
		||||
		img.Init(content)
 | 
			
		||||
 | 
			
		||||
		data, err := img.ToWebP(width, height, fit)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("转换图片失败", err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		w.Header().Set("Content-Type", "image/webp")
 | 
			
		||||
@@ -104,118 +65,6 @@ func main() {
 | 
			
		||||
		w.Write(data)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	http.HandleFunc("/article/", func(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
		// URL 格式: /article/{id}.{格式}?width=320&height=320&fit=cover
 | 
			
		||||
		reg := regexp.MustCompile(`^/article/([0-9a-zA-Z]+).(jpg|jpeg|png|webp)$`)
 | 
			
		||||
		matches := reg.FindStringSubmatch(r.URL.Path)
 | 
			
		||||
		if len(matches) != 3 {
 | 
			
		||||
			log.Println("URL 格式错误", matches)
 | 
			
		||||
			w.WriteHeader(http.StatusNotFound)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		id, format, width, height, fit := matches[1], matches[2], stringToInt(r.URL.Query().Get("width"), 0), stringToInt(r.URL.Query().Get("height"), 0), r.URL.Query().Get("fit")
 | 
			
		||||
		content, err := mysqlConnection.GetArticleImageContent(id)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("获取图片失败", format, err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var img models.Image
 | 
			
		||||
		img.Init(content)
 | 
			
		||||
 | 
			
		||||
		data, err := img.ToWebP(width, height, fit)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Println("转换图片失败", err)
 | 
			
		||||
			w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		w.Header().Set("Content-Type", "image/webp")
 | 
			
		||||
		w.Header().Set("Cache-Control", "max-age=31536000")
 | 
			
		||||
		w.Write(data)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	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" {
 | 
			
		||||
			var gifBin, webpBuf []byte
 | 
			
		||||
			if gifBin, err = os.ReadFile("data/test.gif"); err != nil {
 | 
			
		||||
				log.Println("读取文件失败", err)
 | 
			
		||||
				w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			converter := giftowebp.NewConverter()
 | 
			
		||||
			converter.LoopCompatibility = false // 是否兼容循环动画
 | 
			
		||||
			converter.WebPConfig.SetLossless(0) // 0 有损压缩 1无损压缩
 | 
			
		||||
			converter.WebPConfig.SetMethod(6)   // 压缩速度 0-6 0最快 6质量最好
 | 
			
		||||
			converter.WebPConfig.SetQuality(10) // 压缩质量 0-100
 | 
			
		||||
			converter.WebPAnimEncoderOptions.SetKmin(9)
 | 
			
		||||
			converter.WebPAnimEncoderOptions.SetKmax(17)
 | 
			
		||||
			if webpBuf, err = converter.Convert(gifBin); err != nil {
 | 
			
		||||
				log.Println("编码图像失败", err.Error())
 | 
			
		||||
				w.WriteHeader(http.StatusBadRequest)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			w.Write(webpBuf)
 | 
			
		||||
			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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user