helpers.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package imaging
  2. import (
  3. "fmt"
  4. "image"
  5. "image/color"
  6. _ "image/gif"
  7. "image/jpeg"
  8. "image/png"
  9. "os"
  10. "path/filepath"
  11. "strings"
  12. )
  13. // Open loads an image from file
  14. func Open(filename string) (img image.Image, err error) {
  15. file, err := os.Open(filename)
  16. if err != nil {
  17. return
  18. }
  19. defer file.Close()
  20. img, _, err = image.Decode(file)
  21. if err != nil {
  22. return
  23. }
  24. img = toNRGBA(img)
  25. return
  26. }
  27. // Save saves the image to file with the specified filename.
  28. // The format is determined from the filename extension, "jpg" (or "jpeg") and "png" are supported.
  29. func Save(img image.Image, filename string) (err error) {
  30. format := strings.ToLower(filepath.Ext(filename))
  31. if format != ".jpg" && format != ".jpeg" && format != ".png" {
  32. err = fmt.Errorf("unknown image format: %s", format)
  33. return
  34. }
  35. file, err := os.Create(filename)
  36. if err != nil {
  37. return
  38. }
  39. defer file.Close()
  40. switch format {
  41. case ".jpg", ".jpeg":
  42. var rgba *image.RGBA
  43. if nrgba, ok := img.(*image.NRGBA); ok {
  44. if nrgba.Opaque() {
  45. rgba = &image.RGBA{
  46. Pix: nrgba.Pix,
  47. Stride: nrgba.Stride,
  48. Rect: nrgba.Rect,
  49. }
  50. }
  51. }
  52. if rgba != nil {
  53. err = jpeg.Encode(file, rgba, &jpeg.Options{Quality: 95})
  54. } else {
  55. err = jpeg.Encode(file, img, &jpeg.Options{Quality: 95})
  56. }
  57. case ".png":
  58. err = png.Encode(file, img)
  59. }
  60. return
  61. }
  62. // New creates a new image with the specified width and height, and fills it with the specified color.
  63. func New(width, height int, fillColor color.Color) *image.NRGBA {
  64. dst := image.NewNRGBA(image.Rect(0, 0, width, height))
  65. c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
  66. cs := []uint8{c.R, c.G, c.B, c.A}
  67. // fill the first row
  68. for x := 0; x < width; x++ {
  69. copy(dst.Pix[x*4:(x+1)*4], cs)
  70. }
  71. // copy the first row to other rows
  72. for y := 1; y < height; y++ {
  73. copy(dst.Pix[y*dst.Stride:y*dst.Stride+width*4], dst.Pix[0:width*4])
  74. }
  75. return dst
  76. }
  77. // This function used internally to convert any image type to NRGBA if needed.
  78. func toNRGBA(img image.Image) *image.NRGBA {
  79. srcBounds := img.Bounds()
  80. if srcBounds.Min.X == 0 && srcBounds.Min.Y == 0 {
  81. if src0, ok := img.(*image.NRGBA); ok {
  82. return src0
  83. }
  84. }
  85. return Clone(img)
  86. }