123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- package image
- import (
- "image"
- "image/color"
- )
- // average convert the sums to averages and returns the result.
- func average(sum []uint64, w, h int, n uint64) *image.RGBA {
- ret := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- index := 4 * (y*w + x)
- pix := ret.Pix[y*ret.Stride+x*4:]
- pix[0] = uint8(sum[index+0] / n)
- pix[1] = uint8(sum[index+1] / n)
- pix[2] = uint8(sum[index+2] / n)
- pix[3] = uint8(sum[index+3] / n)
- }
- }
- return ret
- }
- // ResizeRGBA returns a scaled copy of the RGBA image slice r of m.
- // The returned image has width w and height h.
- func ResizeRGBA(m *image.RGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
- }
- // ResizeNRGBA returns a scaled copy of the RGBA image slice r of m.
- // The returned image has width w and height h.
- func ResizeNRGBA(m *image.NRGBA, r image.Rectangle, w, h int) *image.RGBA {
- ww, hh := uint64(w), uint64(h)
- dx, dy := uint64(r.Dx()), uint64(r.Dy())
- // See comment in Resize.
- n, sum := dx*dy, make([]uint64, 4*w*h)
- for y := r.Min.Y; y < r.Max.Y; y++ {
- pix := m.Pix[(y-r.Min.Y)*m.Stride:]
- for x := r.Min.X; x < r.Max.X; x++ {
- // Get the source pixel.
- p := pix[(x-r.Min.X)*4:]
- r64 := uint64(p[0])
- g64 := uint64(p[1])
- b64 := uint64(p[2])
- a64 := uint64(p[3])
- r64 = (r64 * a64) / 255
- g64 = (g64 * a64) / 255
- b64 = (b64 * a64) / 255
- // Spread the source pixel over 1 or more destination rows.
- py := uint64(y) * hh
- for remy := hh; remy > 0; {
- qy := dy - (py % dy)
- if qy > remy {
- qy = remy
- }
- // Spread the source pixel over 1 or more destination columns.
- px := uint64(x) * ww
- index := 4 * ((py/dy)*ww + (px / dx))
- for remx := ww; remx > 0; {
- qx := dx - (px % dx)
- if qx > remx {
- qx = remx
- }
- qxy := qx * qy
- sum[index+0] += r64 * qxy
- sum[index+1] += g64 * qxy
- sum[index+2] += b64 * qxy
- sum[index+3] += a64 * qxy
- index += 4
- px += qx
- remx -= qx
- }
- py += qy
- remy -= qy
- }
- }
- }
- return average(sum, w, h, n)
- }
- // Resample returns a resampled copy of the image slice r of m.
- // The returned image has width w and height h.
- func Resample(m image.Image, r image.Rectangle, w, h int) *image.RGBA {
- if w < 0 || h < 0 {
- return nil
- }
- if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
- return image.NewRGBA(image.Rect(0, 0, w, h))
- }
- curw, curh := r.Dx(), r.Dy()
- img := image.NewRGBA(image.Rect(0, 0, w, h))
- for y := 0; y < h; y++ {
- for x := 0; x < w; x++ {
- // Get a source pixel.
- subx := x * curw / w
- suby := y * curh / h
- r32, g32, b32, a32 := m.At(subx, suby).RGBA()
- r := uint8(r32 >> 8)
- g := uint8(g32 >> 8)
- b := uint8(b32 >> 8)
- a := uint8(a32 >> 8)
- img.SetRGBA(x, y, color.RGBA{r, g, b, a})
- }
- }
- return img
- }
|