image.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package main
  2. import (
  3. "fmt"
  4. "image"
  5. "image/color"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "time"
  11. "golang-fave/engine/wrapper/config"
  12. "golang-fave/utils"
  13. "github.com/disintegration/imaging"
  14. )
  15. func image_generate(width, height int, resize int, fsrc, fdst string) {
  16. src, err := imaging.Open(fsrc)
  17. if err == nil {
  18. if resize == 0 {
  19. src = imaging.Fill(src, width, height, imaging.Center, imaging.Lanczos)
  20. if err := imaging.Save(src, fdst); err != nil {
  21. fmt.Printf("Image generation error (1): %v\n", err)
  22. }
  23. } else if resize == 1 {
  24. src = imaging.Fit(src, width, height, imaging.Lanczos)
  25. if err := imaging.Save(src, fdst); err != nil {
  26. fmt.Printf("Image generation error (2): %v\n", err)
  27. }
  28. } else {
  29. src = imaging.Fit(src, width, height, imaging.Lanczos)
  30. dst := imaging.New(width, height, color.NRGBA{255, 255, 255, 255})
  31. x := 0
  32. y := 0
  33. if src.Bounds().Dx() < width {
  34. x = int((width - src.Bounds().Dx()) / 2)
  35. }
  36. if src.Bounds().Dy() < height {
  37. y = int((height - src.Bounds().Dy()) / 2)
  38. }
  39. dst = imaging.Paste(dst, src, image.Pt(x, y))
  40. if err := imaging.Save(dst, fdst); err != nil {
  41. fmt.Printf("Image generation error (3): %v\n", err)
  42. }
  43. return
  44. }
  45. }
  46. }
  47. func image_create(www, src, dst, typ string, conf *config.Config) {
  48. width := (*conf).Shop.Thumbnails.Thumbnail0[0]
  49. height := (*conf).Shop.Thumbnails.Thumbnail0[1]
  50. resize := 0
  51. if typ == "thumb-1" {
  52. width = (*conf).Shop.Thumbnails.Thumbnail1[0]
  53. height = (*conf).Shop.Thumbnails.Thumbnail1[1]
  54. resize = (*conf).Shop.Thumbnails.Thumbnail1[2]
  55. } else if typ == "thumb-2" {
  56. width = (*conf).Shop.Thumbnails.Thumbnail2[0]
  57. height = (*conf).Shop.Thumbnails.Thumbnail2[1]
  58. resize = (*conf).Shop.Thumbnails.Thumbnail2[2]
  59. } else if typ == "thumb-3" {
  60. width = (*conf).Shop.Thumbnails.Thumbnail3[0]
  61. height = (*conf).Shop.Thumbnails.Thumbnail3[1]
  62. resize = (*conf).Shop.Thumbnails.Thumbnail3[2]
  63. } else if typ == "thumb-full" {
  64. width = (*conf).Shop.Thumbnails.ThumbnailFull[0]
  65. height = (*conf).Shop.Thumbnails.ThumbnailFull[1]
  66. resize = (*conf).Shop.Thumbnails.ThumbnailFull[2]
  67. }
  68. image_generate(width, height, resize, src, dst)
  69. }
  70. func image_detect(www, file string, conf *config.Config) {
  71. index := strings.LastIndex(file, string(os.PathSeparator))
  72. if index != -1 {
  73. file_name := file[index+1:]
  74. if !strings.HasPrefix(file_name, "thumb-") {
  75. file_thumb_0 := file[:index+1] + "thumb-0-" + file_name
  76. file_thumb_1 := file[:index+1] + "thumb-1-" + file_name
  77. file_thumb_2 := file[:index+1] + "thumb-2-" + file_name
  78. file_thumb_3 := file[:index+1] + "thumb-3-" + file_name
  79. file_thumb_full := file[:index+1] + "thumb-full-" + file_name
  80. if !utils.IsFileExists(file_thumb_0) {
  81. image_create(www, file, file_thumb_0, "thumb-0", conf)
  82. }
  83. if !utils.IsFileExists(file_thumb_1) {
  84. image_create(www, file, file_thumb_1, "thumb-1", conf)
  85. }
  86. if !utils.IsFileExists(file_thumb_2) {
  87. image_create(www, file, file_thumb_2, "thumb-2", conf)
  88. }
  89. if !utils.IsFileExists(file_thumb_3) {
  90. image_create(www, file, file_thumb_3, "thumb-3", conf)
  91. }
  92. if !utils.IsFileExists(file_thumb_full) {
  93. image_create(www, file, file_thumb_full, "thumb-full", conf)
  94. }
  95. }
  96. }
  97. }
  98. func image_loop(www_dir string, stop chan bool) {
  99. if dirs, err := ioutil.ReadDir(www_dir); err == nil {
  100. for _, dir := range dirs {
  101. trigger := strings.Join([]string{www_dir, dir.Name(), "tmp", "trigger.img.run"}, string(os.PathSeparator))
  102. if utils.IsFileExists(trigger) {
  103. conf := config.ConfigNew()
  104. if err := conf.ConfigRead(strings.Join([]string{www_dir, dir.Name(), "config", "config.json"}, string(os.PathSeparator))); err == nil {
  105. target_dir := strings.Join([]string{www_dir, dir.Name(), "htdocs", "products", "images"}, string(os.PathSeparator))
  106. if utils.IsDirExists(target_dir) {
  107. pattern := target_dir + string(os.PathSeparator) + "*" + string(os.PathSeparator) + "*.*"
  108. if files, err := filepath.Glob(pattern); err == nil {
  109. for _, file := range files {
  110. select {
  111. case <-stop:
  112. break
  113. default:
  114. image_detect(www_dir, file, conf)
  115. }
  116. }
  117. }
  118. }
  119. }
  120. os.Remove(trigger)
  121. }
  122. }
  123. }
  124. }
  125. func image_start(www_dir string) (chan bool, chan bool) {
  126. ch := make(chan bool)
  127. stop := make(chan bool)
  128. // Run at start
  129. image_loop(www_dir, stop)
  130. go func() {
  131. for {
  132. select {
  133. case <-time.After(2 * time.Second):
  134. // Run every 2 seconds
  135. image_loop(www_dir, stop)
  136. case <-ch:
  137. ch <- true
  138. return
  139. }
  140. }
  141. }()
  142. return ch, stop
  143. }
  144. func image_stop(ch, stop chan bool) {
  145. for {
  146. select {
  147. case stop <- true:
  148. case ch <- true:
  149. <-ch
  150. return
  151. case <-time.After(3 * time.Second):
  152. fmt.Println("Image error: force exit by timeout after 3 seconds")
  153. return
  154. }
  155. }
  156. }