image.go 4.9 KB

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