本帖最后由 魔鬼筋肉人 于 2022-4-12 23:32 编辑
再次根据老哥提示加了return跳出错误,但是又提示fatal error: all goroutines are asleep – deadlock! 好难搞,对于我这种只会css的人来说 if err != nil { return }
—————————— 根据楼层老哥的提示,修改后定位到出错的图片 提示“invalid JPEG format: short Huffman data ” 但是查看图片是可以显示的,暂时不知道怎么解决,我再继续搜索看看,谢谢各位老哥!
—————- 求助,运行提示下面的错误 搜一天了没找到适合的办法
- PS D:img> go run composite_img.go
- panic: runtime error: invalid memory address or nil pointer dereference
- [signal 0xc0000005 code=0x0 addr=0x20 pc=0x2d3415]
-
- goroutine 57 [running]:
- main.main.func1.1()
- D:/img/composite_img.go:142 +0x95
- created by main.main.func1
- D:/img/composite_img.go:137 +0x225
- exit status 2
复制代码
- package main
-
- import (
- _ "embed"
- "fmt"
- "github.com/fogleman/gg"
- "github.com/golang/freetype/truetype"
- "github.com/spf13/viper"
- "image"
- "image/color"
- "image/jpeg"
- "io/ioutil"
- "os"
- "path"
- "path/filepath"
- "strings"
- "sync"
- "time"
- "zip2excel/pkg"
- )
-
- type ImgInfoList struct {
- Path string
- ImgInfo []ImgInfo
- }
-
- type ImgInfo struct {
- Path string
- Size int64
- Name string
- Suffix string
- }
- type taskInfo struct {
- Path string
- Name string
- X int
- Y int
- }
- type imgDraw struct {
- Im image.Image
- X int
- Y int
- StringX float64
- StringY float64
- StringText string
- }
- type Config struct {
- ImgFormat []string
- CompositeDir string
- CompositeLineNum int
- }
-
- var config = new(Config)
-
- //go:embed f.ttf
- var ttf []byte
-
- func init() {
- viper.SetConfigType("toml")
- viper.SetConfigName("config")
- viper.AddConfigPath("./")
- configFile := "./config.toml"
-
- if err := viper.ReadInConfig(); err != nil {
- if _, ok := err.(viper.ConfigFileNotFoundError); ok {
- if err := os.MkdirAll(filepath.Dir(configFile), 0766); err != nil {
- panic(err)
- }
- f, err := os.Create(configFile)
- if err != nil {
- panic(err)
- }
- defer f.Close()
- if err := viper.WriteConfig(); err != nil {
- panic(err)
- }
- } else {
- panic(err)
- }
- }
- if err := viper.Unmarshal(config); err != nil {
- panic(err)
- }
- }
- func main() {
- loadStart := time.Now()
-
- const NX = 115
- const NY = 75
- const NXInterval = 30
- const NYInterval = 100
- strMaxWidth := 115 / 13
- imgListArr := getImgList(config.CompositeDir)
- for _, imgInfoList := range imgListArr {
- var lineNum = config.CompositeLineNum
- imgList := imgInfoList.ImgInfo
- dir := imgInfoList.Path
- //fmt.Printf("n1 的类型 %T", n1)
- filename := dir + "/" +"composite.jpeg"
- //fmt.Println("filename",filename)
- _, err := os.Stat(filename) // 通过获取文件信息进行判断
- if err != nil {
- //fmt.Println("不存在")
- } else {
- continue
- }
-
- imgNum := len(imgList)
- columnNum := imgNum / lineNum
- if imgNum%lineNum != 0 {
- columnNum++
- }
- if imgNum < lineNum {
- lineNum = imgNum
- }
- //fmt.Println(lineNum, columnNum)
- dc := gg.NewContext(lineNum*(NX+NXInterval)-NXInterval, columnNum*(NY+NYInterval))
- dc.SetColor(color.RGBA{R: 39, G: 39, B: 39, A: 255})
- dc.Clear()
-
- ttfFont, _ := truetype.Parse(ttf)
- face := truetype.NewFace(ttfFont, &truetype.Options{
- Size: 13,
- })
-
- dc.SetFontFace(face)
- dc.SetColor(color.RGBA{R: 194, G: 194, B: 194, A: 255})
- imgI := 0
- var wg sync.WaitGroup
- taskChan := make(chan taskInfo, 10)
- imgChan := make(chan imgDraw, 10)
- taskSuccessChan := make(chan bool, 10)
- go func() {
- for {
- select {
- case info := <-taskChan:
- go func() {
- defer wg.Done()
- var x, y int
-
- im, _ := gg.LoadImage(info.Path)
- if im.Bounds().Size().X < im.Bounds().Size().Y {
- im = ScaleImage(im, NY, NX)
- x, y = info.X*(NX+NXInterval)+(NX-NY)/2, info.Y*(NY+NYInterval)
- } else {
- im = ScaleImage(im, NX, NY)
- x, y = info.X*(NX+NXInterval), info.Y*(NY+NYInterval)+(NX-NY)/2
- }
-
- imgChan <- imgDraw{
- Im: im,
- X: x,
- Y: y,
- StringX: float64(info.X * (NX + NXInterval)),
- StringY: float64(info.Y*(NY+NYInterval) + NY + 58),
- StringText: info.Name,
- }
- <-taskSuccessChan
-
- }()
- case imgDrawInfo := <-imgChan:
- dc.DrawImage(imgDrawInfo.Im, imgDrawInfo.X, imgDrawInfo.Y)
- str := getString(imgDrawInfo.StringText, strMaxWidth*2-1)
-
- dc.DrawStringWrapped(str, imgDrawInfo.StringX, imgDrawInfo.StringY, 0, 0, NX, 0, gg.AlignCenter)
- wg.Done()
- }
- }
- }()
-
- for y := 0; y < columnNum; y++ {
- if imgI >= imgNum {
- break
- }
- for x := 0; x < lineNum; x++ {
- if imgI >= imgNum {
- break
- }
- taskChan <- taskInfo{
- Path: imgList[imgI].Path + "/" + imgList[imgI].Name,
- Name: imgList[imgI].Name,
- X: x,
- Y: y,
- }
- taskSuccessChan <- true
- wg.Add(2)
- imgI++
- }
- }
- wg.Wait()
- im := dc.Image()
- f, err := os.Create(dir + "/composite.jpeg")
- if err != nil {
- panic(err)
- }
- jpeg.Encode(f, im, nil)
- fileName := strings.Replace(dir,".\操作区", "", -1)
- defer func() {
- fmt.Println("缩略图生成耗时: ",time.Now().Sub(loadStart).Seconds(),"ms ",fileName)
- }()
- }
-
- }
-
- func getString(str string, maxLen int) string {
- text := ""
- w := 0
- strSize := 0
- for _, c := range []rune(str) {
- if pkg.IsHalfwidth(c) {
- strSize = 1
- } else {
- strSize = 2
- }
- w += strSize
- if w >= maxLen {
- text += "…"
- break
- }
- text += string(c)
- }
- return text
- }
-
- // ScaleImage 缩放图片
- func ScaleImage(image image.Image, x, y int) image.Image {
- //loadStart := time.Now()
- /* defer func() {
- fmt.Printf("缩放耗时: %vn", time.Now().Sub(loadStart).Seconds())
- }() */
- w := image.Bounds().Size().X
- h := image.Bounds().Size().Y
- dc := gg.NewContext(x, y)
- var ax = float64(x) / float64(w)
- var ay = float64(y) / float64(h)
- dc.Scale(ax, ay)
- dc.DrawImage(image, 0, 0)
- return dc.Image()
- }
- func getImgList(p string) (imgInfoListArr []ImgInfoList) {
- files, _ := ioutil.ReadDir(p)
- var imgInfoList ImgInfoList
- imgInfoList.Path = p
- for _, file := range files {
- if !file.IsDir() {
- fileName := file.Name()
- fileSuffix := strings.ToLower(path.Ext(fileName))
- if pkg.StringsContains(config.ImgFormat, fileSuffix) {
- imgInfoList.ImgInfo = append(imgInfoList.ImgInfo, ImgInfo{
- Path: p,
- Size: file.Size(),
- Name: fileName,
- Suffix: fileSuffix,
- })
- }
- } else {
- imgInfoListArr = append(imgInfoListArr, getImgList(p+"/"+file.Name())…)
- }
- }
- if len(imgInfoList.ImgInfo) > 10 {
- imgInfoListArr = append(imgInfoListArr, imgInfoList)
- }
- return imgInfoListArr
- }
复制代码
|