| package imaging |
| |
| import ( |
| "image" |
| ) |
| |
| // Rotate90 rotates the image 90 degrees counterclockwise and returns the transformed image. |
| func Rotate90(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcH |
| dstH := srcW |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstH - dstY - 1 |
| srcY := dstX |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // Rotate180 rotates the image 180 degrees counterclockwise and returns the transformed image. |
| func Rotate180(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcW |
| dstH := srcH |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstW - dstX - 1 |
| srcY := dstH - dstY - 1 |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // Rotate270 rotates the image 270 degrees counterclockwise and returns the transformed image. |
| func Rotate270(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcH |
| dstH := srcW |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstY |
| srcY := dstW - dstX - 1 |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // FlipH flips the image horizontally (from left to right) and returns the transformed image. |
| func FlipH(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcW |
| dstH := srcH |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstW - dstX - 1 |
| srcY := dstY |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // FlipV flips the image vertically (from top to bottom) and returns the transformed image. |
| func FlipV(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcW |
| dstH := srcH |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstX |
| srcY := dstH - dstY - 1 |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // Transpose flips the image horizontally and rotates 90 degrees counter-clockwise. |
| func Transpose(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcH |
| dstH := srcW |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstY |
| srcY := dstX |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |
| |
| // Transverse flips the image vertically and rotates 90 degrees counter-clockwise. |
| func Transverse(img image.Image) *image.NRGBA { |
| src := toNRGBA(img) |
| srcW := src.Bounds().Max.X |
| srcH := src.Bounds().Max.Y |
| dstW := srcH |
| dstH := srcW |
| dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH)) |
| |
| parallel(dstH, func(partStart, partEnd int) { |
| |
| for dstY := partStart; dstY < partEnd; dstY++ { |
| for dstX := 0; dstX < dstW; dstX++ { |
| srcX := dstH - dstY - 1 |
| srcY := dstW - dstX - 1 |
| |
| srcOff := srcY*src.Stride + srcX*4 |
| dstOff := dstY*dst.Stride + dstX*4 |
| |
| copy(dst.Pix[dstOff:dstOff+4], src.Pix[srcOff:srcOff+4]) |
| } |
| } |
| |
| }) |
| |
| return dst |
| } |