create_thumb.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package main
  2. import (
  3. "errors"
  4. // "fmt"
  5. "image"
  6. // "io"
  7. "os"
  8. "path/filepath"
  9. "strconv"
  10. "time"
  11. "github.com/disintegration/imaging"
  12. "github.com/kpango/glg"
  13. "github.com/rwcarlsen/goexif/exif"
  14. "github.com/rwcarlsen/goexif/tiff"
  15. )
  16. func thumbGoOver(thumbType int) bool { // 0 - thumb, 1 - image thumb
  17. glg.Infof("[thumbGoOver] %d files to operate", len(list2CreateThumb))
  18. var glgFunc string // тип раздела для log
  19. if thumbType == 0 {
  20. glgFunc = "TH"
  21. } else {
  22. glgFunc = "iTH"
  23. }
  24. for k, v := range list2CreateThumb {
  25. for len(list2CreateThumbPriority) > 0 { // на паузу, если есть задание на создание приоритетного списка
  26. time.Sleep(1 * time.Second)
  27. }
  28. startTime := time.Now().Round(time.Second) // time check performance
  29. // glg.Debugf("[%s] processing: %s", glgFunc, v)
  30. list2CreateThumb, _ = removeSlice(list2CreateThumb, k) // удаляем запись от списка
  31. if thumbType == 0 { // если thumb creation
  32. if checkIfThumbInCache(v) || !checkIfImg(v) { // если файл существует в кэше или не изображение, то пропускаем ход
  33. continue
  34. }
  35. } else { // если Imgthumb creation
  36. if checkIfImgThumbInCache(v) || !checkIfImg(v) { // если файл существует в кэше или не изображение, то пропускаем ход
  37. continue
  38. }
  39. }
  40. if !checkIfImageExist(v) { // если исходный файл не существует на диск, то возврат с ошибкой
  41. glg.Errorf("[%s] %s not exist", glgFunc, v)
  42. return false
  43. }
  44. if thumbType == 0 {
  45. createThumb(v)
  46. } else {
  47. createImgThumb(v)
  48. }
  49. endTime := time.Now().Round(time.Second) // time check performance
  50. glg.Infof("[%s] %s %s", glgFunc, v, endTime.Sub(startTime))
  51. }
  52. return true
  53. }
  54. func thumbGoOverPriority() {
  55. for {
  56. if len(list2CreateThumbPriority) > 0 {
  57. glg.Infof("[thumbGoOverPriority] %d files to operate", len(list2CreateThumbPriority))
  58. for k, v := range list2CreateThumbPriority {
  59. // fmt.Println("[queue, pri] ", v)
  60. if checkIfThumbInCache(v) || !checkIfImageExist(v) || !checkIfImg(v) { // если файл существует в кэше или исходник отсутствует на диске или это не изображение, то пропускаем ход
  61. list2CreateThumbPriority, _ = removeSlice(list2CreateThumbPriority, k)
  62. continue
  63. }
  64. startTime := time.Now().Round(time.Second) // time check performance
  65. createThumb(v)
  66. endTime := time.Now().Round(time.Second) // time check performance
  67. glg.Infof("[thumb, pri] %s %s", v, endTime.Sub(startTime))
  68. list2CreateThumbPriority, _ = removeSlice(list2CreateThumbPriority, k)
  69. }
  70. }
  71. time.Sleep(1 * time.Second)
  72. }
  73. }
  74. // удаление элемента из слайса
  75. func removeSlice(s []string, index int) ([]string, error) {
  76. if index >= len(s) {
  77. return nil, errors.New("Out of Range Error")
  78. }
  79. // return append(s[:index], s[index+1:]...), nil
  80. s[index] = s[len(s)-1]
  81. s = s[:len(s)-1]
  82. return s, nil
  83. }
  84. // EXIF check orientation
  85. func checkJpegOrientation(path string) int {
  86. var imgOrient *tiff.Tag // exif tag для данные о повороте
  87. if checkIfJpeg(path) {
  88. f, err := os.Open(path) // загрузка файла
  89. check(err)
  90. defer f.Close()
  91. x, err := exif.Decode(f) // декодирование exif
  92. if err != nil { // если отсутствует заголовок exif
  93. return 1
  94. } else { // если заголовок присутствует
  95. imgOrient, err = x.Get(exif.Orientation)
  96. if err != nil {
  97. return 1
  98. }
  99. return str2int(imgOrient.String())
  100. }
  101. } else {
  102. return 1
  103. }
  104. }
  105. // нормализует повернутое изображение
  106. func normalizeOrientation(src image.Image, path string) image.Image {
  107. switch checkJpegOrientation(path) {
  108. case 6:
  109. src = imaging.Rotate270(src)
  110. case 8:
  111. src = imaging.Rotate90(src)
  112. case 3:
  113. src = imaging.Rotate180(src)
  114. }
  115. return src
  116. }
  117. // создание thumb
  118. func createThumb(filename string) {
  119. src, err := imaging.Open(config.PathImages + filename)
  120. if err != nil {
  121. glg.Errorf("[createThumb] %s, open failed: %v", config.PathImages+filename, err)
  122. return
  123. }
  124. src = normalizeOrientation(src, config.PathImages+filename) // нормализация повернутого изображения
  125. // ! src = imaging.Fill(src, 155, 103, imaging.Center, imaging.Lanczos)
  126. src = imaging.Thumbnail(src, 155, 103, imaging.Lanczos)
  127. // Save the resulting image using JPEG format.
  128. saveFilename := config.PathCacheThumb + filename
  129. if !checkIfThumbInCache(saveFilename) { // если отсутствует папка, то создает
  130. os.Mkdir(config.PathCacheThumb+filepath.Dir(filename), 0644)
  131. }
  132. err = imaging.Save(src, saveFilename)
  133. if err != nil {
  134. glg.Errorf("[createThumb] %s,save failed: %v", config.PathImages+filename, err)
  135. }
  136. }
  137. // создание ImgThumb
  138. func createImgThumb(filename string) {
  139. src, err := imaging.Open(config.PathImages + filename)
  140. if err != nil {
  141. glg.Errorf("[createImgThumb] %s, open failed: %v", config.PathImages+filename, err)
  142. return
  143. }
  144. src = normalizeOrientation(src, config.PathImages+filename) // нормализация повернутого изображения
  145. src = imaging.Fit(src, 800, 600, imaging.Box)
  146. //src = imaging.Fill(src, 800, 480, imaging.Center, imaging.Lanczos)
  147. // Save the resulting image using JPEG format.
  148. saveFilename := config.PathCacheImages + filename
  149. if !checkIfThumbInCache(saveFilename) { // если отсутствует папка, то создает
  150. os.Mkdir(config.PathCacheImages+filepath.Dir(filename), 0644)
  151. }
  152. err = imaging.Save(src, saveFilename)
  153. if err != nil {
  154. glg.Errorf("[createImgThumb] %s,save failed: %v", config.PathImages+filename, err)
  155. }
  156. }
  157. // преобразование строки в число
  158. func str2int(val string) int {
  159. i, _ := strconv.Atoi(val)
  160. return i
  161. }