本文整理匯總了Golang中image/color.RGBA64類的典型用法代碼示例。如果您正苦於以下問題:Golang RGBA64類的具體用法?Golang RGBA64怎麽用?Golang RGBA64使用的例子?那麽, 這裏精選的類代碼示例或許可以為您提供幫助。
在下文中一共展示了RGBA64類的12個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: getGaussianNoisePixel
func getGaussianNoisePixel(k1, k2, expectation float64, pixel color.RGBA64) color.RGBA64 {
gnPixel := color.RGBA64{}
gnPixel.B = getGaussianNoiseValue(pixel.B, k1, k2, expectation)
gnPixel.R = getGaussianNoiseValue(pixel.R, k1, k2, expectation)
gnPixel.G = getGaussianNoiseValue(pixel.G, k1, k2, expectation)
return gnPixel
}
示例2: getLinearNoisePixel
func getLinearNoisePixel(pixel color.RGBA64, a, b uint32) color.RGBA64 {
lnPixel := color.RGBA64{}
lnPixel.R = getLinearNoiseValue(pixel.R, a, b)
lnPixel.G = getLinearNoiseValue(pixel.G, a, b)
lnPixel.B = getLinearNoiseValue(pixel.B, a, b)
return lnPixel
}
示例3: interpolateColor
func interpolateColor(c1, c2 color.Color, where float64) color.Color {
r1, g1, b1, a1 := c1.RGBA()
r2, g2, b2, a2 := c2.RGBA()
var c color.RGBA64
c.R = uint16(float64(r2-r1)*where + float64(r1) + 0.5)
c.G = uint16(float64(g2-g1)*where + float64(g1) + 0.5)
c.B = uint16(float64(b2-b1)*where + float64(b1) + 0.5)
c.A = uint16(float64(a2-a1)*where + float64(a1) + 0.5)
return c
}
示例4: Draw
func (burkes) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
quantError0 := make([][3]int32, r.Dx()+4)
quantError1 := make([][3]int32, r.Dx()+4)
out := color.RGBA64{A: 0xffff}
for y := 0; y != r.Dy(); y++ {
for x := 0; x != r.Dx(); x++ {
sr, sg, sb, _ := src.At(sp.X+x, sp.Y+y).RGBA()
er, eg, eb := int32(sr), int32(sg), int32(sb)
er = clamp(er + quantError0[x+2][0]/32)
eg = clamp(eg + quantError0[x+2][1]/32)
eb = clamp(eb + quantError0[x+2][2]/32)
out.R = uint16(er)
out.G = uint16(eg)
out.B = uint16(eb)
dst.Set(r.Min.X+x, r.Min.Y+y, &out)
sr, sg, sb, _ = dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
er -= int32(sr)
eg -= int32(sg)
eb -= int32(sb)
quantError0[x+3][0] += er * 8
quantError0[x+3][1] += eg * 8
quantError0[x+3][2] += eb * 8
quantError0[x+4][0] += er * 4
quantError0[x+4][1] += eg * 4
quantError0[x+4][2] += eb * 4
quantError1[x+0][0] += er * 2
quantError1[x+0][1] += eg * 2
quantError1[x+0][2] += eb * 2
quantError1[x+1][0] += er * 4
quantError1[x+1][1] += eg * 4
quantError1[x+1][2] += eb * 4
quantError1[x+2][0] += er * 8
quantError1[x+2][1] += eg * 8
quantError1[x+2][2] += eb * 8
quantError1[x+3][0] += er * 4
quantError1[x+3][1] += eg * 4
quantError1[x+3][2] += eb * 4
quantError1[x+4][0] += er * 2
quantError1[x+4][1] += eg * 2
quantError1[x+4][2] += eb * 2
}
// Recycle the quantization error buffers.
quantError0, quantError1 = quantError1, quantError0
for i := range quantError1 {
quantError1[i] = [3]int32{}
}
}
}
示例5: rasterizeOpSrc
func (z *Rasterizer) rasterizeOpSrc(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
z.accumulateMask()
out := color.RGBA64{}
outc := color.Color(&out)
for y, y1 := 0, r.Max.Y-r.Min.Y; y < y1; y++ {
for x, x1 := 0, r.Max.X-r.Min.X; x < x1; x++ {
sr, sg, sb, sa := src.At(sp.X+x, sp.Y+y).RGBA()
ma := z.bufU32[y*z.size.X+x]
// This algorithm comes from the standard library's image/draw
// package.
out.R = uint16(sr * ma / 0xffff)
out.G = uint16(sg * ma / 0xffff)
out.B = uint16(sb * ma / 0xffff)
out.A = uint16(sa * ma / 0xffff)
dst.Set(r.Min.X+x, r.Min.Y+y, outc)
}
}
}
示例6: Draw
func (falseFloydSteinberg) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
quantErrorNext := make([][3]int32, r.Dx()+1)
out := color.RGBA64{A: 0xffff}
for y := 0; y != r.Dy(); y++ {
quantError := [3]int32{}
quantErrorNext[0] = [3]int32{}
for x := 0; x != r.Dx(); x++ {
sr, sg, sb, _ := src.At(sp.X+x, sp.Y+y).RGBA()
er, eg, eb := int32(sr), int32(sg), int32(sb)
er = clamp(er + (quantErrorNext[x][0]+quantError[0])/16)
eg = clamp(eg + (quantErrorNext[x][1]+quantError[1])/16)
eb = clamp(eb + (quantErrorNext[x][2]+quantError[2])/16)
out.R = uint16(er)
out.G = uint16(eg)
out.B = uint16(eb)
dst.Set(r.Min.X+x, r.Min.Y+y, &out)
sr, sg, sb, _ = dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
er -= int32(sr)
eg -= int32(sg)
eb -= int32(sb)
quantError[0] = er * 3
quantError[1] = eg * 3
quantError[2] = eb * 3
quantErrorNext[x+0][0] += er * 3
quantErrorNext[x+0][1] += eg * 3
quantErrorNext[x+0][2] += eb * 3
quantErrorNext[x+1][0] = er * 2
quantErrorNext[x+1][1] = eg * 2
quantErrorNext[x+1][2] = eb * 2
}
}
}
示例7: bilinearGeneral
func bilinearGeneral(src image.Image, x, y float64) color.Color {
p := findLinearSrc(src.Bounds(), x, y)
var fr, fg, fb, fa float64
var r, g, b, a uint32
r, g, b, a = src.At(p.low.X, p.low.Y).RGBA()
fr += float64(r) * p.frac00
fg += float64(g) * p.frac00
fb += float64(b) * p.frac00
fa += float64(a) * p.frac00
r, g, b, a = src.At(p.high.X, p.low.Y).RGBA()
fr += float64(r) * p.frac01
fg += float64(g) * p.frac01
fb += float64(b) * p.frac01
fa += float64(a) * p.frac01
r, g, b, a = src.At(p.low.X, p.high.Y).RGBA()
fr += float64(r) * p.frac10
fg += float64(g) * p.frac10
fb += float64(b) * p.frac10
fa += float64(a) * p.frac10
r, g, b, a = src.At(p.high.X, p.high.Y).RGBA()
fr += float64(r) * p.frac11
fg += float64(g) * p.frac11
fb += float64(b) * p.frac11
fa += float64(a) * p.frac11
var c color.RGBA64
c.R = uint16(fr + 0.5)
c.G = uint16(fg + 0.5)
c.B = uint16(fb + 0.5)
c.A = uint16(fa + 0.5)
return c
}
示例8: drawPaletted
func drawPaletted(dst Image, r image.Rectangle, src image.Image, sp image.Point, floydSteinberg bool) {
// TODO(nigeltao): handle the case where the dst and src overlap.
// Does it even make sense to try and do Floyd-Steinberg whilst
// walking the image backward (right-to-left bottom-to-top)?
// If dst is an *image.Paletted, we have a fast path for dst.Set and
// dst.At. The dst.Set equivalent is a batch version of the algorithm
// used by color.Palette's Index method in image/color/color.go, plus
// optional Floyd-Steinberg error diffusion.
palette, pix, stride := [][3]int32(nil), []byte(nil), 0
if p, ok := dst.(*image.Paletted); ok {
palette = make([][3]int32, len(p.Palette))
for i, col := range p.Palette {
r, g, b, _ := col.RGBA()
palette[i][0] = int32(r)
palette[i][1] = int32(g)
palette[i][2] = int32(b)
}
pix, stride = p.Pix[p.PixOffset(r.Min.X, r.Min.Y):], p.Stride
}
// quantErrorCurr and quantErrorNext are the Floyd-Steinberg quantization
// errors that have been propagated to the pixels in the current and next
// rows. The +2 simplifies calculation near the edges.
var quantErrorCurr, quantErrorNext [][3]int32
if floydSteinberg {
quantErrorCurr = make([][3]int32, r.Dx()+2)
quantErrorNext = make([][3]int32, r.Dx()+2)
}
// Loop over each source pixel.
out := color.RGBA64{A: 0xffff}
for y := 0; y != r.Dy(); y++ {
for x := 0; x != r.Dx(); x++ {
// er, eg and eb are the pixel's R,G,B values plus the
// optional Floyd-Steinberg error.
sr, sg, sb, _ := src.At(sp.X+x, sp.Y+y).RGBA()
er, eg, eb := int32(sr), int32(sg), int32(sb)
if floydSteinberg {
er = clamp(er + quantErrorCurr[x+1][0]/16)
eg = clamp(eg + quantErrorCurr[x+1][1]/16)
eb = clamp(eb + quantErrorCurr[x+1][2]/16)
}
if palette != nil {
// Find the closest palette color in Euclidean R,G,B space: the
// one that minimizes sum-squared-difference. We shift by 1 bit
// to avoid potential uint32 overflow in sum-squared-difference.
// TODO(nigeltao): consider smarter algorithms.
bestIndex, bestSSD := 0, uint32(1<<32-1)
for index, p := range palette {
delta := (er - p[0]) >> 1
ssd := uint32(delta * delta)
delta = (eg - p[1]) >> 1
ssd += uint32(delta * delta)
delta = (eb - p[2]) >> 1
ssd += uint32(delta * delta)
if ssd < bestSSD {
bestIndex, bestSSD = index, ssd
if ssd == 0 {
break
}
}
}
pix[y*stride+x] = byte(bestIndex)
if !floydSteinberg {
continue
}
er -= int32(palette[bestIndex][0])
eg -= int32(palette[bestIndex][1])
eb -= int32(palette[bestIndex][2])
} else {
out.R = uint16(er)
out.G = uint16(eg)
out.B = uint16(eb)
// The third argument is &out instead of out (and out is
// declared outside of the inner loop) to avoid the implicit
// conversion to color.Color here allocating memory in the
// inner loop if sizeof(color.RGBA64) > sizeof(uintptr).
dst.Set(r.Min.X+x, r.Min.Y+y, &out)
if !floydSteinberg {
continue
}
sr, sg, sb, _ = dst.At(r.Min.X+x, r.Min.Y+y).RGBA()
er -= int32(sr)
eg -= int32(sg)
eb -= int32(sb)
}
// Propagate the Floyd-Steinberg quantization error.
quantErrorNext[x+0][0] += er * 3
quantErrorNext[x+0][1] += eg * 3
quantErrorNext[x+0][2] += eb * 3
quantErrorNext[x+1][0] += er * 5
quantErrorNext[x+1][1] += eg * 5
quantErrorNext[x+1][2] += eb * 5
quantErrorNext[x+2][0] += er * 1
//.........這裏部分代碼省略.........
示例9: DrawMask
// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r
// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) {
clip(dst, &r, src, &sp, mask, &mp)
if r.Empty() {
return
}
// Fast paths for special cases. If none of them apply, then we fall back to a general but slow implementation.
switch dst0 := dst.(type) {
case *image.RGBA:
if op == Over {
if mask == nil {
switch src0 := src.(type) {
case *image.Uniform:
drawFillOver(dst0, r, src0)
return
case *image.RGBA:
drawCopyOver(dst0, r, src0, sp)
return
case *image.NRGBA:
drawNRGBAOver(dst0, r, src0, sp)
return
case *image.YCbCr:
if drawYCbCr(dst0, r, src0, sp) {
return
}
}
} else if mask0, ok := mask.(*image.Alpha); ok {
switch src0 := src.(type) {
case *image.Uniform:
drawGlyphOver(dst0, r, src0, mask0, mp)
return
}
}
} else {
if mask == nil {
switch src0 := src.(type) {
case *image.Uniform:
drawFillSrc(dst0, r, src0)
return
case *image.RGBA:
drawCopySrc(dst0, r, src0, sp)
return
case *image.NRGBA:
drawNRGBASrc(dst0, r, src0, sp)
return
case *image.YCbCr:
if drawYCbCr(dst0, r, src0, sp) {
return
}
}
}
}
drawRGBA(dst0, r, src, sp, mask, mp, op)
return
case *image.Paletted:
if op == Src && mask == nil && !processBackward(dst, r, src, sp) {
drawPaletted(dst0, r, src, sp, false)
}
}
x0, x1, dx := r.Min.X, r.Max.X, 1
y0, y1, dy := r.Min.Y, r.Max.Y, 1
if processBackward(dst, r, src, sp) {
x0, x1, dx = x1-1, x0-1, -1
y0, y1, dy = y1-1, y0-1, -1
}
var out color.RGBA64
sy := sp.Y + y0 - r.Min.Y
my := mp.Y + y0 - r.Min.Y
for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy {
sx := sp.X + x0 - r.Min.X
mx := mp.X + x0 - r.Min.X
for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx {
ma := uint32(m)
if mask != nil {
_, _, _, ma = mask.At(mx, my).RGBA()
}
switch {
case ma == 0:
if op == Over {
// No-op.
} else {
dst.Set(x, y, color.Transparent)
}
case ma == m && op == Src:
dst.Set(x, y, src.At(sx, sy))
default:
sr, sg, sb, sa := src.At(sx, sy).RGBA()
if op == Over {
dr, dg, db, da := dst.At(x, y).RGBA()
a := m - (sa * ma / m)
out.R = uint16((dr*a + sr*ma) / m)
out.G = uint16((dg*a + sg*ma) / m)
out.B = uint16((db*a + sb*ma) / m)
out.A = uint16((da*a + sa*ma) / m)
} else {
out.R = uint16(sr * ma / m)
//.........這裏部分代碼省略.........
示例10: DrawMask
// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r
// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.
func DrawMask(dst Image, r image.Rectangle, src image.Image, sp image.Point, mask image.Image, mp image.Point, op Op) {
clip(dst, &r, src, &sp, mask, &mp)
if r.Empty() {
return
}
// Fast paths for special cases. If none of them apply, then we fall back to a general but slow implementation.
if dst0, ok := dst.(*image.RGBA); ok {
if op == Over {
if mask == nil {
switch src0 := src.(type) {
case *image.Uniform:
drawFillOver(dst0, r, src0)
return
case *image.RGBA:
drawCopyOver(dst0, r, src0, sp)
return
case *image.NRGBA:
drawNRGBAOver(dst0, r, src0, sp)
return
case *ycbcr.YCbCr:
drawYCbCr(dst0, r, src0, sp)
return
}
} else if mask0, ok := mask.(*image.Alpha); ok {
switch src0 := src.(type) {
case *image.Uniform:
drawGlyphOver(dst0, r, src0, mask0, mp)
return
}
}
} else {
if mask == nil {
switch src0 := src.(type) {
case *image.Uniform:
drawFillSrc(dst0, r, src0)
return
case *image.RGBA:
drawCopySrc(dst0, r, src0, sp)
return
case *image.NRGBA:
drawNRGBASrc(dst0, r, src0, sp)
return
case *ycbcr.YCbCr:
drawYCbCr(dst0, r, src0, sp)
return
}
}
}
drawRGBA(dst0, r, src, sp, mask, mp, op)
return
}
x0, x1, dx := r.Min.X, r.Max.X, 1
y0, y1, dy := r.Min.Y, r.Max.Y, 1
if image.Image(dst) == src && r.Overlaps(r.Add(sp.Sub(r.Min))) {
// Rectangles overlap: process backward?
if sp.Y < r.Min.Y || sp.Y == r.Min.Y && sp.X < r.Min.X {
x0, x1, dx = x1-1, x0-1, -1
y0, y1, dy = y1-1, y0-1, -1
}
}
var out *color.RGBA64
sy := sp.Y + y0 - r.Min.Y
my := mp.Y + y0 - r.Min.Y
for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy {
sx := sp.X + x0 - r.Min.X
mx := mp.X + x0 - r.Min.X
for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx {
ma := uint32(m)
if mask != nil {
_, _, _, ma = mask.At(mx, my).RGBA()
}
switch {
case ma == 0:
if op == Over {
// No-op.
} else {
dst.Set(x, y, color.Transparent)
}
case ma == m && op == Src:
dst.Set(x, y, src.At(sx, sy))
default:
sr, sg, sb, sa := src.At(sx, sy).RGBA()
if out == nil {
out = new(color.RGBA64)
}
if op == Over {
dr, dg, db, da := dst.At(x, y).RGBA()
a := m - (sa * ma / m)
out.R = uint16((dr*a + sr*ma) / m)
out.G = uint16((dg*a + sg*ma) / m)
out.B = uint16((db*a + sb*ma) / m)
out.A = uint16((da*a + sa*ma) / m)
} else {
out.R = uint16(sr * ma / m)
out.G = uint16(sg * ma / m)
//.........這裏部分代碼省略.........
示例11: readImagePass
// readImagePass reads a single image pass, sized according to the pass number.
func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) {
var bitsPerPixel int = 0
pixOffset := 0
var (
gray *image.Gray
rgba *image.RGBA
paletted *image.Paletted
nrgba *image.NRGBA
gray16 *image.Gray16
rgba64 *image.RGBA64
nrgba64 *image.NRGBA64
img image.Image
)
width, height := d.width, d.height
if d.interlace == itAdam7 && !allocateOnly {
p := interlacing[pass]
// Add the multiplication factor and subtract one, effectively rounding up.
width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
}
switch d.cb {
case cbG1, cbG2, cbG4, cbG8:
bitsPerPixel = d.depth
gray = image.NewGray(image.Rect(0, 0, width, height))
img = gray
case cbGA8:
bitsPerPixel = 16
nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
img = nrgba
case cbTC8:
bitsPerPixel = 24
rgba = image.NewRGBA(image.Rect(0, 0, width, height))
img = rgba
case cbP1, cbP2, cbP4, cbP8:
bitsPerPixel = d.depth
paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette)
img = paletted
case cbTCA8:
bitsPerPixel = 32
nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
img = nrgba
case cbG16:
bitsPerPixel = 16
gray16 = image.NewGray16(image.Rect(0, 0, width, height))
img = gray16
case cbGA16:
bitsPerPixel = 32
nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
img = nrgba64
case cbTC16:
bitsPerPixel = 48
rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height))
img = rgba64
case cbTCA16:
bitsPerPixel = 64
nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
img = nrgba64
}
if allocateOnly {
return img, nil
}
bytesPerPixel := (bitsPerPixel + 7) / 8
// The +1 is for the per-row filter type, which is at cr[0].
rowSize := 1 + (bitsPerPixel*width+7)/8
// cr and pr are the bytes for the current and previous row.
cr := make([]uint8, rowSize)
pr := make([]uint8, rowSize)
for y := 0; y < height; y++ {
// Read the decompressed bytes.
_, err := io.ReadFull(r, cr)
if err != nil {
if err == io.EOF || err == io.ErrUnexpectedEOF {
return nil, FormatError("not enough pixel data")
}
return nil, err
}
// Apply the filter.
cdat := cr[1:]
pdat := pr[1:]
switch cr[0] {
case ftNone:
// No-op.
case ftSub:
for i := bytesPerPixel; i < len(cdat); i++ {
cdat[i] += cdat[i-bytesPerPixel]
}
case ftUp:
for i, p := range pdat {
cdat[i] += p
}
case ftAverage:
for i := 0; i < bytesPerPixel; i++ {
cdat[i] += pdat[i] / 2
}
for i := bytesPerPixel; i < len(cdat); i++ {
cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
//.........這裏部分代碼省略.........
示例12: DrawMask
// DrawMask aligns r.Min in dst with sp in src and mp in mask and then replaces the rectangle r
// in dst with the result of a Porter-Duff composition. A nil mask is treated as opaque.
// The implementation is simple and slow.
// TODO(nigeltao): Optimize this.
func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Image, mp Point, op Op) {
dx, dy := src.Width()-sp.X, src.Height()-sp.Y
if mask != nil {
if dx > mask.Width()-mp.X {
dx = mask.Width() - mp.X
}
if dy > mask.Height()-mp.Y {
dy = mask.Height() - mp.Y
}
}
if r.Dx() > dx {
r.Max.X = r.Min.X + dx
}
if r.Dy() > dy {
r.Max.Y = r.Min.Y + dy
}
// TODO(nigeltao): Clip r to dst's bounding box, and handle the case when sp or mp has negative X or Y.
// TODO(nigeltao): Ensure that r is well formed, i.e. r.Max.X >= r.Min.X and likewise for Y.
// Fast paths for special cases. If none of them apply, then we fall back to a general but slow implementation.
switch dst0 := dst.(type) {
case *image.RGBA:
if op == Over {
if mask == nil {
if src0, ok := src.(image.Uniform); ok {
drawFillOver(dst0, r, src0)
return
}
if src0, ok := src.(*image.RGBA); ok {
if dst0 == src0 && r.Overlaps(r.Add(sp.Sub(r.Min))) {
// TODO(nigeltao): Implement a fast path for the overlapping case.
} else {
drawCopyOver(dst0, r, src0, sp)
return
}
}
} else if mask0, ok := mask.(*image.Alpha); ok {
if src0, ok := src.(image.Uniform); ok {
drawGlyphOver(dst0, r, src0, mask0, mp)
return
}
}
} else {
if mask == nil {
if src0, ok := src.(image.Uniform); ok {
drawFillSrc(dst0, r, src0)
return
}
if src0, ok := src.(*image.RGBA); ok {
if dst0 == src0 && r.Overlaps(r.Add(sp.Sub(r.Min))) {
// TODO(nigeltao): Implement a fast path for the overlapping case.
} else {
drawCopySrc(dst0, r, src0, sp)
return
}
}
}
}
drawRGBA(dst0, r, src, sp, mask, mp, op)
return
case DrawMasker:
// Destination might wish to perform the draw operation itself
if dst0.DrawMask(r, src, sp, mask, mp, op) {
return
}
}
x0, x1, dx := r.Min.X, r.Max.X, 1
y0, y1, dy := r.Min.Y, r.Max.Y, 1
if image.Image(dst) == src && r.Overlaps(r.Add(sp.Sub(r.Min))) {
// Rectangles overlap: process backward?
if sp.Y < r.Min.Y || sp.Y == r.Min.Y && sp.X < r.Min.X {
x0, x1, dx = x1-1, x0-1, -1
y0, y1, dy = y1-1, y0-1, -1
}
}
var out *color.RGBA64
sy := sp.Y + y0 - r.Min.Y
my := mp.Y + y0 - r.Min.Y
for y := y0; y != y1; y, sy, my = y+dy, sy+dy, my+dy {
sx := sp.X + x0 - r.Min.X
mx := mp.X + x0 - r.Min.X
for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx {
ma := uint32(m)
if mask != nil {
_, _, _, ma = mask.At(mx, my).RGBA()
}
switch {
case ma == 0:
if op == Over {
// No-op.
} else {
dst.Set(x, y, zeroColor)
}
case ma == m && op == Src:
//.........這裏部分代碼省略.........