transform.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package imaging
  2. import (
  3. "image"
  4. )
  5. // Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image.
  6. func Rotate90(img image.Image) *image.NRGBA {
  7. src := toNRGBA(img)
  8. srcW := src.Bounds().Max.X
  9. srcH := src.Bounds().Max.Y
  10. dstW := srcH
  11. dstH := srcW
  12. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  13. parallel(dstH, func(partStart, partEnd int) {
  14. for dstY := partStart; dstY < partEnd; dstY++ {
  15. for dstX := 0; dstX < dstW; dstX++ {
  16. srcX := dstH - dstY - 1
  17. srcY := dstX
  18. srcOff := srcY*src.Stride + srcX*4
  19. dstOff := dstY*dst.Stride + dstX*4
  20. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  21. }
  22. }
  23. })
  24. return dst
  25. }
  26. // Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image.
  27. func Rotate180(img image.Image) *image.NRGBA {
  28. src := toNRGBA(img)
  29. srcW := src.Bounds().Max.X
  30. srcH := src.Bounds().Max.Y
  31. dstW := srcW
  32. dstH := srcH
  33. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  34. parallel(dstH, func(partStart, partEnd int) {
  35. for dstY := partStart; dstY < partEnd; dstY++ {
  36. for dstX := 0; dstX < dstW; dstX++ {
  37. srcX := dstW - dstX - 1
  38. srcY := dstH - dstY - 1
  39. srcOff := srcY*src.Stride + srcX*4
  40. dstOff := dstY*dst.Stride + dstX*4
  41. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  42. }
  43. }
  44. })
  45. return dst
  46. }
  47. // Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image.
  48. func Rotate270(img image.Image) *image.NRGBA {
  49. src := toNRGBA(img)
  50. srcW := src.Bounds().Max.X
  51. srcH := src.Bounds().Max.Y
  52. dstW := srcH
  53. dstH := srcW
  54. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  55. parallel(dstH, func(partStart, partEnd int) {
  56. for dstY := partStart; dstY < partEnd; dstY++ {
  57. for dstX := 0; dstX < dstW; dstX++ {
  58. srcX := dstY
  59. srcY := dstW - dstX - 1
  60. srcOff := srcY*src.Stride + srcX*4
  61. dstOff := dstY*dst.Stride + dstX*4
  62. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  63. }
  64. }
  65. })
  66. return dst
  67. }
  68. // FlipH flips the image horizontally (from left to right) and returns the transformed image.
  69. func FlipH(img image.Image) *image.NRGBA {
  70. src := toNRGBA(img)
  71. srcW := src.Bounds().Max.X
  72. srcH := src.Bounds().Max.Y
  73. dstW := srcW
  74. dstH := srcH
  75. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  76. parallel(dstH, func(partStart, partEnd int) {
  77. for dstY := partStart; dstY < partEnd; dstY++ {
  78. for dstX := 0; dstX < dstW; dstX++ {
  79. srcX := dstW - dstX - 1
  80. srcY := dstY
  81. srcOff := srcY*src.Stride + srcX*4
  82. dstOff := dstY*dst.Stride + dstX*4
  83. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  84. }
  85. }
  86. })
  87. return dst
  88. }
  89. // FlipV flips the image vertically (from top to bottom) and returns the transformed image.
  90. func FlipV(img image.Image) *image.NRGBA {
  91. src := toNRGBA(img)
  92. srcW := src.Bounds().Max.X
  93. srcH := src.Bounds().Max.Y
  94. dstW := srcW
  95. dstH := srcH
  96. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  97. parallel(dstH, func(partStart, partEnd int) {
  98. for dstY := partStart; dstY < partEnd; dstY++ {
  99. for dstX := 0; dstX < dstW; dstX++ {
  100. srcX := dstX
  101. srcY := dstH - dstY - 1
  102. srcOff := srcY*src.Stride + srcX*4
  103. dstOff := dstY*dst.Stride + dstX*4
  104. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  105. }
  106. }
  107. })
  108. return dst
  109. }
  110. // Transpose flips the image horizontally and rotates 90 degrees counter-clockwise.
  111. func Transpose(img image.Image) *image.NRGBA {
  112. src := toNRGBA(img)
  113. srcW := src.Bounds().Max.X
  114. srcH := src.Bounds().Max.Y
  115. dstW := srcH
  116. dstH := srcW
  117. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  118. parallel(dstH, func(partStart, partEnd int) {
  119. for dstY := partStart; dstY < partEnd; dstY++ {
  120. for dstX := 0; dstX < dstW; dstX++ {
  121. srcX := dstY
  122. srcY := dstX
  123. srcOff := srcY*src.Stride + srcX*4
  124. dstOff := dstY*dst.Stride + dstX*4
  125. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  126. }
  127. }
  128. })
  129. return dst
  130. }
  131. // Transverse flips the image vertically and rotates 90 degrees counter-clockwise.
  132. func Transverse(img image.Image) *image.NRGBA {
  133. src := toNRGBA(img)
  134. srcW := src.Bounds().Max.X
  135. srcH := src.Bounds().Max.Y
  136. dstW := srcH
  137. dstH := srcW
  138. dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
  139. parallel(dstH, func(partStart, partEnd int) {
  140. for dstY := partStart; dstY < partEnd; dstY++ {
  141. for dstX := 0; dstX < dstW; dstX++ {
  142. srcX := dstH - dstY - 1
  143. srcY := dstW - dstX - 1
  144. srcOff := srcY*src.Stride + srcX*4
  145. dstOff := dstY*dst.Stride + dstX*4
  146. copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4])
  147. }
  148. }
  149. })
  150. return dst
  151. }