imgSlice.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package service
  2. import (
  3. "fmt"
  4. "github.com/nfnt/resize"
  5. "github.com/pkg/errors"
  6. "image"
  7. "image/jpeg"
  8. "image/png"
  9. "os"
  10. "path/filepath"
  11. "time"
  12. )
  13. func saveCroppedImage(img image.Image, imgName string, imgType string, row, col int) error {
  14. // 生成文件名(例如 part_0_0.jpg)
  15. saveDir := fmt.Sprintf("uploads/%s", time.Now().Format("2006-01-02"))
  16. os.MkdirAll(saveDir, 0755)
  17. filename := filepath.Join(saveDir, fmt.Sprintf("%s_%d_%d.%s", imgName, row, col, imgType))
  18. outFile, err := os.Create(filename)
  19. if err != nil {
  20. return err
  21. }
  22. defer outFile.Close()
  23. // 可选:调整子图尺寸(使用 resize 库)
  24. resizedImg := resize.Resize(300, 0, img, resize.Lanczos3)
  25. // 编码为 JPEG 并保存[1](@ref)
  26. if imgType == "jpeg" {
  27. if err := jpeg.Encode(outFile, resizedImg, &jpeg.Options{Quality: 100}); err != nil {
  28. return err
  29. }
  30. } else if imgType == "png" {
  31. if err := png.Encode(outFile, resizedImg); err != nil {
  32. return err
  33. }
  34. } else {
  35. return errors.New("格式暂不支持")
  36. }
  37. return nil
  38. }
  39. func SliceImg(imagePath string, imgName string) error {
  40. // 打开图片
  41. file, err := os.Open(imagePath)
  42. if err != nil {
  43. return errors.New("打开图片失败")
  44. }
  45. defer file.Close()
  46. // 解码图片
  47. img, imgType, err := image.Decode(file)
  48. if err != nil {
  49. fmt.Println(err)
  50. return errors.New("解码图片失败")
  51. }
  52. // 获取原始图片尺寸
  53. bounds := img.Bounds()
  54. width, height := bounds.Max.X, bounds.Max.Y
  55. // 计算每个小块的尺寸(假设原图可被3整除)
  56. blockWidth := width / 3
  57. blockHeight := height / 3
  58. // 循环切割九宫格
  59. for row := 0; row < 3; row++ {
  60. for col := 0; col < 3; col++ {
  61. // 定义裁剪区域
  62. rect := image.Rect(
  63. col*blockWidth, // 起始X
  64. row*blockHeight, // 起始Y
  65. (col+1)*blockWidth, // 结束X
  66. (row+1)*blockHeight, // 结束Y
  67. )
  68. // 使用 SubImage 裁剪[3](@ref)
  69. croppedImg := img.(interface {
  70. SubImage(r image.Rectangle) image.Image
  71. }).SubImage(rect)
  72. // 保存文件(可选缩放)
  73. err = saveCroppedImage(croppedImg, imgName, imgType, row, col)
  74. if err != nil {
  75. return errors.New("保存切片图片失败")
  76. }
  77. }
  78. }
  79. return nil
  80. }