func DrawBottomRightPattern(avatar *image.RGBA) { // Mirror bottom left quadrant to right bottom quadrant for y := AvatarSize / 2; y < AvatarSize; y++ { for x := 0; x < AvatarSize; x++ { if x < AvatarSize/2 { avatar.Set(AvatarSize-x-1, y, avatar.At(x, y)) } } } }
func DrawTopRightPattern(avatar *image.RGBA) { // Mirror top left quadrant to right top quadrant for y := 0; y < AvatarSize; y++ { for x := 0; x < AvatarSize; x++ { if x < AvatarSize/2 { avatar.Set(AvatarSize-x-1, y, avatar.At(x, y)) } } } }
func ApplyToImage(i *image.RGBA, f FilterTripleProvider) { w, h := i.Rect.Max.X, i.Rect.Max.Y filter := Pipeline(16, true, Chain(f, Clamp{0, 1})).GetTriple() for x := 0; x < w; x++ { for y := 0; y < h; y++ { r, g, b, _ := i.At(x, y).RGBA() i.Set(x, y, filter(RGB{float64(r), float64(g), float64(b)}).(RGB)) } } }
func main() { flag.Parse() var res *image.RGBA n := 0 for i := *start; ; i++ { n++ name := fmt.Sprintf(*in, i) f, err := os.Open(name) if err != nil { log.Printf("Open(%q): %v", name, err) break } img, _, err := image.Decode(f) if err != nil { log.Fatal("Failed to decode image %q: %v", name, err) } f.Close() log.Printf("Open(%q): OK", name) if res == nil { res = image.NewRGBA(img.Bounds()) for i := range res.Pix { if i%4 == 3 { res.Pix[i] = 255 } else { res.Pix[i] = 0 } } } // Apply "right" color from the current frame to the result. for i := 0; i < img.Bounds().Dx(); i++ { for j := 0; j < img.Bounds().Dy(); j++ { clr := img.At(img.Bounds().Min.X+i, img.Bounds().Min.Y+j) cur := res.At(img.Bounds().Min.X+i, img.Bounds().Min.Y+j) if pwr(clr) > pwr(cur) { r, g, b, _ := clr.RGBA() idx := 4 * (j*img.Bounds().Dx() + i) res.Pix[idx] = max(res.Pix[idx], uint8(r>>8)) res.Pix[idx+1] = max(res.Pix[idx+1], uint8(g>>8)) res.Pix[idx+2] = max(res.Pix[idx+2], uint8(b>>8)) } } } mustWrite(fmt.Sprintf(*out, n), res) mustWrite(fmt.Sprintf(*orig, n), img) } if res == nil { return } mustWrite(*final, res) }
//srcImgのsrcRectを dstImgのdstRectにコピ- func clipAfromB(srcImg *image.RGBA, srcRect image.Rectangle, dstImg *image.RGBA, dstRect image.Rectangle) { for x := 0; x < srcRect.Max.X; x++ { for y := 0; y < srcRect.Max.Y; y++ { srcRGBA := srcImg.At(x, y) _, _, _, a := srcRGBA.RGBA() if a == 0 { //0は透明 continue } dstImg.Set(dstRect.Min.X+x, dstRect.Min.Y+y, srcRGBA) } } }
func plot(img *image.RGBA, x, y int, c *color.RGBA) { r0, g0, b0, a0 := img.At(x, y).RGBA() // background color r1, g1, b1, a1 := c.RGBA() // foreground color var alpha0 float64 = float64(a0) / float64(0xff) // background alpha var alpha1 float64 = float64(a1) / float64(0xff) // foreground alpha // resulting colors var r uint8 = uint8(alpha1*float64(r1) + (1.0-alpha1)*float64(r0)) var g uint8 = uint8(alpha1*float64(g1) + (1.0-alpha1)*float64(g0)) var b uint8 = uint8(alpha1*float64(b1) + (1.0-alpha1)*float64(b0)) var a uint8 = uint8(0xff * (alpha1 + alpha0*(1.0-alpha1))) pxl := color.RGBA{r, g, b, a} // resulting pixel img.Set(x, y, pxl) }
func flipRGBA(src *image.RGBA) { srcCopy := image.NewRGBA(src.Bounds()) for y := 0; y < src.Bounds().Max.Y-src.Bounds().Min.Y; y++ { for x := 0; x < src.Bounds().Max.X-src.Bounds().Min.X; x++ { srcCopy.Set(x, y, src.At(x, y)) } } for y := 0; y < src.Bounds().Max.Y-src.Bounds().Min.Y; y++ { for x := 0; x < src.Bounds().Max.X-src.Bounds().Min.X; x++ { src.Set(x, y, srcCopy.At(x, (src.Bounds().Max.Y-src.Bounds().Min.Y)-1-y)) } } }
func getNumBlackPixels(rgba *image.RGBA) int { s := 0 for y := 0; y < rgba.Bounds().Dy(); y++ { for x := 0; x < rgba.Bounds().Dx(); x++ { col := rgba.At(x, y) r, g, b, _ := col.RGBA() s += (mono(r) + mono(g) + mono(b)) } } if *negative { return 3*(rgba.Bounds().Dy()*rgba.Bounds().Dx()) - s } else { return s } }
// fill a polygon using 4-way flood fill algorithm func Fill4(img *image.RGBA, x0, y0 int, c *color.RGBA) { r0, g0, b0, a0 := img.At(x0, y0).RGBA() var floodFill func(x0, y0 int) floodFill = func(x0, y0 int) { r1, g1, b1, a1 := img.At(x0, y0).RGBA() if r0 == r1 && g0 == g1 && b0 == b1 && a0 == a1 { img.Set(x0, y0, c) floodFill(x0 - 1, y0) floodFill(x0 + 1, y0) floodFill(x0, y0 - 1) floodFill(x0, y0 + 1) } } floodFill(x0, y0) }
func (tis *Tis) AddTile(img *image.RGBA) int { newImg := image.NewRGBA(image.Rect(0, 0, 64, 64)) bounds := img.Bounds() for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { c := img.At(x, y) //_,_,_,a := c.RGBA() newImg.Set(x, y, c) } } tis.imgTiles = append(tis.imgTiles, newImg) return len(tis.imgTiles) - 1 }
// 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.Image { 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*m.Stride:] for x := r.Min.X; x < r.Max.X; x++ { // Get the source pixel. p := m.At(x, y).(color.RGBA) // p := pix[x] r64 := uint64(p.R) g64 := uint64(p.G) b64 := uint64(p.B) a64 := uint64(p.A) // 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) }
func imageEq(m0, m1 *image.RGBA) bool { b0 := m0.Bounds() b1 := m1.Bounds() if b0 != b1 { return false } badPx := 0 for y := b0.Min.Y; y < b0.Max.Y; y++ { for x := b0.Min.X; x < b0.Max.X; x++ { c0, c1 := m0.At(x, y).(color.RGBA), m1.At(x, y).(color.RGBA) if !colorEq(c0, c1) { badPx++ } } } badFrac := float64(badPx) / float64(b0.Dx()*b0.Dy()) return badFrac < 0.01 }
func Splatter(avatar *image.RGBA, nameBytes []byte, pixelColor color.RGBA) { // A somewhat random number based on the username. var nameSum int64 for i := range nameBytes { nameSum += int64(nameBytes[i]) } // Use said number to keep random-ness deterministic for a given name rand.Seed(nameSum) // Make the "splatter" for y := 0; y < AvatarSize; y++ { for x := 0; x < AvatarSize; x++ { if ((x + y) % 2) == 0 { if rand.Intn(2) == 1 { avatar.SetRGBA(x, y, pixelColor) } } } } // Mirror left half to right half for y := 0; y < AvatarSize; y++ { for x := 0; x < AvatarSize; x++ { if x < AvatarSize/2 { avatar.Set(AvatarSize-x-1, y, avatar.At(x, y)) } } } // Mirror top to bottom for y := 0; y < AvatarSize; y++ { for x := 0; x < AvatarSize; x++ { if y < AvatarSize/2 { avatar.Set(x, AvatarSize-y-1, avatar.At(x, y)) } } } }
func (t *wave) wave(src, dst *image.RGBA, dx, dy int) { var ( dstx float64 a uint32 x, y int ) if t.algo && rand.Intn(2) == 0 { t.d1 *= -1 } for y = 0; y < src.Bounds().Dy(); y++ { if y == t.liney { dx += 1 continue } for x = 0; x < src.Bounds().Dx(); x++ { if _, _, _, a = src.At(x, y).RGBA(); a > 0 { dstx = float64(dx+x+t.delta) + float64(t.d1)*math.Sin(6.28*float64(y)/float64(t.d2)) dst.Set(int(dstx), y, src.At(x, y)) } } } }
func (sgImage *SgImage) setAlphaPixel(img *image.RGBA, x, y int, c2 uint8) { alpha := ((c2 & 0x1f) << 3) | ((c2 & 0x1c) >> 2) c := img.At(x, y) r, g, b, _ := c.RGBA() img.Set(x, y, color.RGBA{uint8(r), uint8(g), uint8(b), alpha}) }