image.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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) bool {
  71. result := false
  72. index := strings.LastIndex(file, string(os.PathSeparator))
  73. if index != -1 {
  74. file_name := file[index+1:]
  75. if !strings.HasPrefix(file_name, "thumb-") {
  76. file_thumb_0 := file[:index+1] + "thumb-0-" + file_name
  77. file_thumb_1 := file[:index+1] + "thumb-1-" + file_name
  78. file_thumb_2 := file[:index+1] + "thumb-2-" + file_name
  79. file_thumb_3 := file[:index+1] + "thumb-3-" + file_name
  80. file_thumb_full := file[:index+1] + "thumb-full-" + file_name
  81. if !utils.IsFileExists(file_thumb_0) {
  82. image_create(www, file, file_thumb_0, "thumb-0", conf)
  83. result = true
  84. }
  85. if !utils.IsFileExists(file_thumb_1) {
  86. image_create(www, file, file_thumb_1, "thumb-1", conf)
  87. result = true
  88. }
  89. if !utils.IsFileExists(file_thumb_2) {
  90. image_create(www, file, file_thumb_2, "thumb-2", conf)
  91. result = true
  92. }
  93. if !utils.IsFileExists(file_thumb_3) {
  94. image_create(www, file, file_thumb_3, "thumb-3", conf)
  95. result = true
  96. }
  97. if !utils.IsFileExists(file_thumb_full) {
  98. image_create(www, file, file_thumb_full, "thumb-full", conf)
  99. result = true
  100. }
  101. }
  102. }
  103. return result
  104. }
  105. func image_loop(www_dir string, stop chan bool) {
  106. if dirs, err := ioutil.ReadDir(www_dir); err == nil {
  107. for _, dir := range dirs {
  108. trigger := strings.Join([]string{www_dir, dir.Name(), "tmp", "trigger.img.run"}, string(os.PathSeparator))
  109. if utils.IsFileExists(trigger) {
  110. processed := false
  111. conf := config.ConfigNew()
  112. if err := conf.ConfigRead(strings.Join([]string{www_dir, dir.Name(), "config", "config.json"}, string(os.PathSeparator))); err == nil {
  113. target_dir := strings.Join([]string{www_dir, dir.Name(), "htdocs", "products", "images"}, string(os.PathSeparator))
  114. if utils.IsDirExists(target_dir) {
  115. pattern := target_dir + string(os.PathSeparator) + "*" + string(os.PathSeparator) + "*.*"
  116. if files, err := filepath.Glob(pattern); err == nil {
  117. for _, file := range files {
  118. select {
  119. case <-stop:
  120. break
  121. default:
  122. if image_detect(www_dir, file, conf) {
  123. if !processed {
  124. processed = true
  125. }
  126. }
  127. }
  128. }
  129. }
  130. }
  131. }
  132. if !processed {
  133. os.Remove(trigger)
  134. }
  135. }
  136. }
  137. }
  138. }
  139. func image_start(www_dir string) (chan bool, chan bool) {
  140. ch := make(chan bool)
  141. stop := make(chan bool)
  142. go func() {
  143. for {
  144. select {
  145. case <-time.After(2 * time.Second):
  146. // Run every 2 seconds
  147. image_loop(www_dir, stop)
  148. case <-ch:
  149. ch <- true
  150. return
  151. }
  152. }
  153. }()
  154. return ch, stop
  155. }
  156. func image_stop(ch, stop chan bool) {
  157. for {
  158. select {
  159. case stop <- true:
  160. case ch <- true:
  161. <-ch
  162. return
  163. case <-time.After(3 * time.Second):
  164. fmt.Println("Image error: force exit by timeout after 3 seconds")
  165. return
  166. }
  167. }
  168. }