Example #1
0
func mapToColor(o map[string]interface{}) color.Color {
	var c color.RGBA

	// Because JavaScript
	switch x := o["r"].(type) {
	case int64:
		c.R = uint8(colorF(float64(x)))
	case float64:
		c.R = uint8(colorF(x))
	}
	switch x := o["g"].(type) {
	case int64:
		c.G = uint8(colorF(float64(x)))
	case float64:
		c.G = uint8(colorF(x))
	}
	switch x := o["b"].(type) {
	case int64:
		c.B = uint8(colorF(float64(x)))
	case float64:
		c.B = uint8(colorF(x))
	}
	c.A = 0xff
	return c
}
func (cf *ColorFinder) findMainColor(colorMap *map[color.RGBA]colorStats, shift uint, targetColor *shiftedRGBA) shiftedRGBA {
	colorWeights := make(map[shiftedRGBA]float64)

	bounds := cf.img.Bounds()
	stepLength := stepLength(bounds)

	for y := bounds.Min.Y; y < bounds.Max.Y; y += stepLength {
		for x := bounds.Min.X; x < bounds.Max.X; x += stepLength {
			r, g, b, a := cf.img.At(x, y).RGBA()
			color := color.RGBA{}
			color.R = uint8(r >> shiftRGB)
			color.G = uint8(g >> shiftRGB)
			color.B = uint8(b >> shiftRGB)
			color.A = uint8(a >> shiftRGB)

			if rgbMatchesTargetColor(targetColor, &color) {
				increaseColorWeight(&colorWeights, colorMap, &color, shift)
			}
		}
	}

	maxColor := shiftedRGBA{}
	maxWeight := 0.0
	for sRGB, weight := range colorWeights {
		if weight > maxWeight {
			maxColor = sRGB
			maxWeight = weight
		}
	}

	return maxColor
}
Example #3
0
func superSampling(inputImage image.Image) image.Image {
	rect := inputImage.Bounds()
	width := rect.Size().X
	height := rect.Size().Y
	rect2 := image.Rect(rect.Min.X, rect.Min.Y, rect.Max.X-1, rect.Max.Y-1)
	rgba := image.NewRGBA(rect2)

	for x := 0; x < width-1; x++ {
		for y := 0; y < height-1; y++ {
			var col color.RGBA
			// 座標(x,y)のR, G, B, α の値を取得
			r00, g00, b00, a00 := inputImage.At(x, y).RGBA()
			r01, g01, b01, a01 := inputImage.At(x, y+1).RGBA()
			r10, g10, b10, a10 := inputImage.At(x+1, y).RGBA()
			r11, g11, b11, a11 := inputImage.At(x+1, y+1).RGBA()
			col.R = uint8((uint(uint8(r00)) + uint(uint8(r01)) + uint(uint8(r10)) + uint(uint8(r11))) / 4)
			col.G = uint8((uint(uint8(g00)) + uint(uint8(g01)) + uint(uint8(g10)) + uint(uint8(g11))) / 4)
			col.B = uint8((uint(uint8(b00)) + uint(uint8(b01)) + uint(uint8(b10)) + uint(uint8(b11))) / 4)
			col.A = uint8((uint(uint8(a00)) + uint(uint8(a01)) + uint(uint8(a10)) + uint(uint8(a11))) / 4)
			rgba.Set(x, y, col)
		}
	}

	return rgba.SubImage(rect)
}
Example #4
0
// Convert a []float64 to an image, reading data with the format specified in
// chans (e.g. RGBA, BGRA, BRG, RRR). If a component is not specified in the
func FromSliceChans(img *Image, chans string, fill float64, data []float64) {
	surf := img.Surf
	cm := surf.ColorModel()
	b := surf.Bounds()
	minX, maxX := b.Min.X, b.Max.X
	minY, maxY := b.Min.Y, b.Max.Y
	k := 0
	nc := len(chans)

	const mk = 0xff
	dfill := clamp8(fill) & mk

	for i := minY; i < maxY; i++ {
		for j := minX; j < maxX; j++ {
			outCol := color.RGBA{dfill, dfill, dfill, dfill}
			for c := 0; c < nc; c++ {
				switch chans[c] {
				case 'r', 'R':
					outCol.R = clamp8(data[k+c]) & mk
				case 'g', 'G':
					outCol.G = clamp8(data[k+c]) & mk
				case 'b', 'B':
					outCol.B = clamp8(data[k+c]) & mk
				case 'a', 'A':
					outCol.A = clamp8(data[k+c]) & mk
				default:
					// Just skip the channel
				}
			}
			k += nc
			img.Surf.Set(j, i, cm.Convert(outCol))
		}
	}
}
Example #5
0
func main() {
	img := shapes.FilledImage(500, 300, image.White)

	fill := color.RGBA{200, 200, 200, 255}

	for i := 0; i < 10; i++ {
		width, height := 50+(20*i), 30+(10*i)

		rect, err := shapes.New("rectangle", shapes.Option{Fill: fill, Rect: image.Rect(0, 0, width, height), Filled: true})
		if err != nil {
			log.Fatal(err)
		}

		x := 10 + (20 * i)
		for j := i / 2; j >= 0; j-- {
			rect.Draw(img, x+j, (x/2)+j)
		}

		fill.R -= uint8(i * 5)
		fill.G = fill.R
		fill.B = fill.R
	}

	shapes.SaveImage(img, "rectangle.png")
}
func (cf *ColorFinder) buildColorMap() *map[color.RGBA]colorStats {
	colorMap := make(map[color.RGBA]colorStats)
	bounds := cf.img.Bounds()

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r, g, b, a := cf.img.At(x, y).RGBA()
			rgb := color.RGBA{}
			rgb.R = uint8(r >> shiftRGB)
			rgb.G = uint8(g >> shiftRGB)
			rgb.B = uint8(b >> shiftRGB)
			rgb.A = uint8(a >> shiftRGB)

			colrStats, exist := colorMap[rgb]
			if exist {
				colrStats.count++
			} else {
				colrStats := colorStats{count: 1, weight: weight(&rgb)}
				if colrStats.weight <= 0 {
					colrStats.weight = 1e-10
				}
				colorMap[rgb] = colrStats
			}
		}
	}
	return &colorMap
}
// Return the complementary color
func Complementary(v color.RGBA) [2]color.RGBA {
	var result color.RGBA
	result.R = 255 - v.R
	result.G = 255 - v.G
	result.B = 255 - v.B
	result.A = v.A
	return [2]color.RGBA{v, result}
}
Example #8
0
// Apply the given color mapping to the specified image buffers.
func Apply(from, to *Rule, src, dst draw.Image) {
	var x, y int
	var r, g, b, a uint32
	var sc color.Color
	var dc color.RGBA
	var pix pixel

	rect := src.Bounds()

	for y = 0; y < rect.Dy(); y++ {
		for x = 0; x < rect.Dx(); x++ {
			sc = src.At(x, y)

			r, g, b, a = sc.RGBA()
			pix.r = uint8(r >> 8)
			pix.g = uint8(g >> 8)
			pix.b = uint8(b >> 8)
			pix.a = uint8(a >> 8)

			// Check if the pixel matches the filter rule.
			if !(match(pix.r, from.R) && match(pix.g, from.G) && match(pix.b, from.B) && match(pix.a, from.A)) {
				dst.Set(x, y, sc)
				continue
			}

			// Compute three different types of grayscale conversion.
			// These can be applied by named references.
			pix.average = uint8(((r + g + b) / 3) >> 8)
			pix.lightness = uint8(((min(min(r, g), b) + max(max(r, g), b)) / 2) >> 8)

			// For luminosity it is necessary to apply an inverse of the gamma
			// function for the color space before calculating the inner product.
			// Then you apply the gamma function to the reduced value. Failure to
			// incorporate the gamma function can result in errors of up to 20%.
			//
			// For typical computer stuff, the color space is sRGB. The right
			// numbers for sRGB are approx. 0.21, 0.72, 0.07. Gamma for sRGB
			// is a composite function that approximates exponentiation by 1/2.2
			//
			// This is a rather expensive operation, but gives a much more accurate
			// and satisfactory result than the average and lightness versions.
			pix.luminosity = gammaSRGB(
				0.212655*invGammaSRGB(pix.r) +
					0.715158*invGammaSRGB(pix.g) +
					0.072187*invGammaSRGB(pix.b))

			// Transform color.
			dc.R = transform(&pix, pix.r, to.R)
			dc.G = transform(&pix, pix.g, to.G)
			dc.B = transform(&pix, pix.b, to.B)
			dc.A = transform(&pix, pix.a, to.A)

			// Set new pixel.
			dst.Set(x, y, dc)
		}
	}
}
Example #9
0
func setAlpha(c color.RGBA, a uint8) color.RGBA {
	if c.A == 0 {
		return c
	}
	c.R = mult(c.R, a, c.A)
	c.G = mult(c.G, a, c.A)
	c.B = mult(c.B, a, c.A)
	c.A = a
	return c
}
Example #10
0
// SetAll sets the given values for the channels
func (d *Dioder) SetAll(colorSet color.RGBA) {
	d.ColorConfiguration = colorSet
	//Red
	colorSet.R = calculateOpacity(colorSet.R, colorSet.A)
	d.SetChannelInteger(colorSet.R, d.PinConfiguration.Red)
	//Green
	colorSet.G = calculateOpacity(colorSet.G, colorSet.A)
	d.SetChannelInteger(colorSet.G, d.PinConfiguration.Green)

	//Blue
	colorSet.B = calculateOpacity(colorSet.B, colorSet.A)
	d.SetChannelInteger(colorSet.B, d.PinConfiguration.Blue)
}
Example #11
0
func drawworld2(translate *noise.Translate, w *worldgen2.World, img draw.Image) {
	w.Log = false
	bounds := img.Bounds()

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			var c color.RGBA
			c.A = 255
			posx, posy := translate.Into(float64(x), float64(y))
			per := w.GetHeight_Island(posx, posy)

			if per < 0 {
				v := uint8(255 - 127*(-per))
				c.R = 0
				c.G = 0
				c.B = v
			} else if per < 0.00002 {
				v := uint8(255 - 2550*per)
				c.R = v
				c.G = v
				c.B = 0
			} else if per > 0.34 {
				v := uint8(220 * (per))
				c.R = v
				c.G = v
				c.B = v
			} else {
				//v := uint8(255-per*255)
				v := uint8(255 - per*300)
				c.R = 0
				c.G = v
				c.B = 0
			}
			img.Set(x, y, c)
		}
	}
	w.Log = true
}
Example #12
0
func parseColors(args []*ast.BasicLit) (color.RGBA, error) {
	ints := make([]uint8, 4)
	var ret color.RGBA
	var u uint8
	for i := range args {
		v := args[i]
		switch v.Kind {
		case token.FLOAT:
			f, err := strconv.ParseFloat(args[i].Value, 8)
			if err != nil {
				return ret, err
			}
			// Has to be alpha, or bust
			u = uint8(f * 100)
		case token.INT:
			i, err := strconv.Atoi(v.Value)
			if err != nil {
				return ret, err
			}
			u = uint8(i)
		case token.COLOR:
			if i != 0 {
				return ret, fmt.Errorf("hex is only allowed as the first argumetn found: % #v", v)
			}
			var err error
			ret, err = ast.ColorFromHexString(v.Value)
			if err != nil {
				return ret, err
			}
			// This is only allowed as the first argument
			i = i + 2
		default:
			log.Fatalf("unsupported kind %s % #v\n", v.Kind, v)
		}
		ints[i] = u
	}
	if ints[0] > 0 {
		ret.R = ints[0]
	}
	if ints[1] > 0 {
		ret.G = ints[1]
	}
	if ints[2] > 0 {
		ret.B = ints[2]
	}
	if ints[3] > 0 {
		ret.A = ints[3]
	}
	return ret, nil
}
Example #13
0
func imfilterMerg(filter [][]float32, fX, fY, x, y, xoffset, yoffset int, rgbFunc func(xpos, ypos int) (r0, g0, b0, a0 uint8), mergFunc func(a, b float32) float32) color.RGBA {
	_, _, _, a := rgbFunc(x, y)
	newColor := color.RGBA{R: 0, G: 0, B: 0, A: a}
	for xx := 0; xx < fX; xx++ {
		for yy := 0; yy < fY; yy++ {
			r, g, b, _ := rgbFunc(x+xx-xoffset, y+yy-yoffset)
			newColor.R = oneColorCorrect(float32(newColor.R) + mergFunc(filter[xx][yy], float32(r)))
			if r != g {
				newColor.G = oneColorCorrect(float32(newColor.G) + mergFunc(filter[xx][yy], float32(g)))
			} else {
				newColor.G = newColor.R
			}
			switch b {
			case r:
				newColor.B = newColor.R
			case g:
				newColor.B = newColor.G
			default:
				newColor.B = oneColorCorrect(float32(newColor.B) + mergFunc(filter[xx][yy], float32(b)))
			}
		}
	}
	return newColor
}
Example #14
0
func blend(orig image.Image) (m image.Image) {
	// deviation range
	dev := uint16(50 << 8)

	c := new(color.RGBA)
	c.A = 255

	bounds := orig.Bounds()

	// iterations
	for i := 0; i < 10; i++ {
		newm := image.NewRGBA(bounds)

		for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
			for x := bounds.Min.X; x < bounds.Max.X; x++ {

				var r, g, b, ct uint32

				_r, _g, _b, _ := orig.At(x, y).RGBA()

				for i := -1; i < 2; i++ {
					for j := -1; j < 2; j++ {
						rt, gt, bt, _ := orig.At(x+i, y+j).RGBA()

						if uint16(rt-_r) > dev || uint16(gt-_g) > dev || uint16(bt-_b) > dev {
							continue
						}

						r += rt
						g += gt
						b += bt
						ct++
					}
				}
				c.R = uint8((r / ct) >> 8)
				c.G = uint8((g / ct) >> 8)
				c.B = uint8((b / ct) >> 8)

				newm.Set(x, y, c)

			}
		}

		m = newm
	}

	return
}
Example #15
0
func main() {
	img := shapes.FilledImage(420, 220, image.White)
	fill := color.RGBA{200, 200, 200, 0xFF} // light gray
	for i := 0; i < 10; i++ {
		width, height := 40+(20*i), 20+(10*i)
		rectangle := shapes.Rectangle{fill,
			image.Rect(0, 0, width, height), true}
		x := 10 + (20 * i)
		for j := i / 2; j >= 0; j-- {
			rectangle.Draw(img, x+j, (x/2)+j)
		}
		fill.R -= uint8(i * 5)
		fill.G = fill.R
		fill.B = fill.R
	}
	shapes.SaveImage(img, "rectangle.png")
}
func DrawImage(src image.Image, dest draw.Image, tr MatrixTransform, op draw.Op, filter ImageFilter) {
	bounds := src.Bounds()
	x0, y0, x1, y1 := float64(bounds.Min.X), float64(bounds.Min.Y), float64(bounds.Max.X), float64(bounds.Max.Y)
	tr.TransformRectangle(&x0, &y0, &x1, &y1)
	var x, y, u, v float64
	var c1, c2, cr color.Color
	var r, g, b, a, ia, r1, g1, b1, a1, r2, g2, b2, a2 uint32
	var color color.RGBA
	for x = x0; x < x1; x++ {
		for y = y0; y < y1; y++ {
			u = x
			v = y
			tr.InverseTransform(&u, &v)
			if bounds.Min.X <= int(u) && bounds.Max.X > int(u) && bounds.Min.Y <= int(v) && bounds.Max.Y > int(v) {
				c1 = dest.At(int(x), int(y))
				switch filter {
				case LinearFilter:
					c2 = src.At(int(u), int(v))
				case BilinearFilter:
					c2 = getColorBilinear(src, u, v)
				case BicubicFilter:
					c2 = getColorBicubic(src, u, v)
				}
				switch op {
				case draw.Over:
					r1, g1, b1, a1 = c1.RGBA()
					r2, g2, b2, a2 = c2.RGBA()
					ia = M - a2
					r = ((r1 * ia) / M) + r2
					g = ((g1 * ia) / M) + g2
					b = ((b1 * ia) / M) + b2
					a = ((a1 * ia) / M) + a2
					color.R = uint8(r >> 8)
					color.G = uint8(g >> 8)
					color.B = uint8(b >> 8)
					color.A = uint8(a >> 8)
					cr = color
				default:
					cr = c2
				}
				dest.Set(int(x), int(y), cr)
			}
		}
	}
}
Example #17
0
// linterp performs linear interpolation between the first (p[0]) and
// the last (pal[len(p) - 1]) colors in palette "pal". It fills the
// remaining (pal[1:len(p) - 1]) palette slots with the intepolated
// colors. Colors in slots pal[0] and pal[len(p) - 1] MUST be of type
// color.RGBA. The remaining slots will also be filled with colors of
// type color.RGBA
func linterp(pal color.Palette) {
	n := len(pal)
	if n <= 2 {
		return
	}
	s, e := pal[0].(color.RGBA), pal[n-1].(color.RGBA)
	dr := int(e.R) - int(s.R)
	dg := int(e.G) - int(s.G)
	db := int(e.B) - int(s.B)
	da := int(e.A) - int(s.A)
	for i := 1; i < n-1; i++ {
		c := color.RGBA{}
		c.R = uint8(int(s.R) + i*dr/(n-1))
		c.G = uint8(int(s.G) + i*dg/(n-1))
		c.B = uint8(int(s.B) + i*db/(n-1))
		c.A = uint8(int(s.A) + i*da/(n-1))
		pal[i] = c
	}
}
//Takes a list of words (i.e. from a book), finds words that match the search term,
//and creates an image based on the usage of those words with each pixel representing
//the specified number of words (sectionSize). The channel will be sent a value of 1
//upon the successful completion of the task
func CreateImage(words []string, searchTerm string, sectionSize int, quit chan int) {
	searchTerms := strings.Fields(searchTerm)

	imageHeight := 20

	//Setup the image
	totalWords := len(words)
	imageWidth := int(math.Ceil(float64(totalWords) / float64(sectionSize)))
	newImg := image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))

	usedInSection := make([]bool, imageWidth, imageWidth)

	usedCount := 0

	for index, word := range words {
		section := int(math.Floor(float64(index) / float64(sectionSize)))
		for _, term := range searchTerms {
			if word == term {
				usedInSection[section] = true
				usedCount++
				break
			}
		}
	}

	fmt.Println("The terms", searchTerm, "were found", usedCount, "times")

	for x := 0; x < imageWidth; x++ {
		color := color.RGBA{255, 255, 255, 255}
		if usedInSection[x] == true {
			color.R = 0
			color.G = 0
			color.B = 0
		}
		for y := 0; y < imageHeight; y++ {
			newImg.SetRGBA(x, y, color)
		}
	}

	SaveImage(searchTerm+".png", newImg)

	quit <- 1
}
Example #19
0
// colorOpColor combines two colors with the requested operation
// applying appropriate overflows as Sass expects
func colorOpColor(tok token.Token, x, y *BasicLit, combine bool) (*BasicLit, error) {
	colX, err := ColorFromHexString(x.Value)
	if err != nil {
		return nil, err
	}
	colY, err := ColorFromHexString(y.Value)
	if err != nil {
		return nil, err
	}

	var z color.RGBA
	z.R = overflowMath(tok, colX.R, colY.R)
	z.G = overflowMath(tok, colX.G, colY.G)
	z.B = overflowMath(tok, colX.B, colY.B)

	s := colorToHex(z)
	return &BasicLit{
		Kind:  token.COLOR,
		Value: LookupColor(s),
	}, nil
}
Example #20
0
func main() {
	start := time.Now()

	const pictureSize = 5000
	img := image.NewRGBA(image.Rect(0, 0, pictureSize, pictureSize))

	f, err := os.OpenFile("mandel.png", os.O_WRONLY|os.O_CREATE, 0666)

	if err != nil {
		fmt.Printf("Can't create picture file\n")
	}

	deltaX := math.Abs(float64(-2.0-1.0)) / float64(pictureSize)

	deltaY := math.Abs(float64(-1.0-1.0)) / float64(pictureSize)

	cx := float64(-2.0)
	for x := 0; x < pictureSize; x++ {
		cx += deltaX
		cy := float64(-1.0)
		for y := 0; y < pictureSize; y++ {
			cy += deltaY
			iter := PointIteration(cx, cy, 255.0, 255)

			col := color.RGBA{255, iter, iter, iter}
			col.A = 255
			col.R = iter
			col.G = iter
			col.B = iter
			img.Set(x, y, col)
		}
	}

	w := bufio.NewWriter(f)
	png.Encode(w, img)
	w.Flush()

	fmt.Printf("Seconds needed %d\n", time.Now().Sub(start))
}
Example #21
0
func (bilinear) RGBA(src *image.RGBA, x, y float64) color.RGBA {
	p := findLinearSrc(src.Bounds(), x, y)

	// Array offsets for the surrounding pixels.
	off00 := offRGBA(src, p.low.X, p.low.Y)
	off01 := offRGBA(src, p.high.X, p.low.Y)
	off10 := offRGBA(src, p.low.X, p.high.Y)
	off11 := offRGBA(src, p.high.X, p.high.Y)

	var fr, fg, fb, fa float64

	fr += float64(src.Pix[off00+0]) * p.frac00
	fg += float64(src.Pix[off00+1]) * p.frac00
	fb += float64(src.Pix[off00+2]) * p.frac00
	fa += float64(src.Pix[off00+3]) * p.frac00

	fr += float64(src.Pix[off01+0]) * p.frac01
	fg += float64(src.Pix[off01+1]) * p.frac01
	fb += float64(src.Pix[off01+2]) * p.frac01
	fa += float64(src.Pix[off01+3]) * p.frac01

	fr += float64(src.Pix[off10+0]) * p.frac10
	fg += float64(src.Pix[off10+1]) * p.frac10
	fb += float64(src.Pix[off10+2]) * p.frac10
	fa += float64(src.Pix[off10+3]) * p.frac10

	fr += float64(src.Pix[off11+0]) * p.frac11
	fg += float64(src.Pix[off11+1]) * p.frac11
	fb += float64(src.Pix[off11+2]) * p.frac11
	fa += float64(src.Pix[off11+3]) * p.frac11

	var c color.RGBA
	c.R = uint8(fr + 0.5)
	c.G = uint8(fg + 0.5)
	c.B = uint8(fb + 0.5)
	c.A = uint8(fa + 0.5)
	return c
}
Example #22
0
func (me *renderTile) getSample(x, y, z int, col *color.RGBA) {
	if (x >= SceneSize) || (y >= SceneSize) || (z >= SceneSize) {
		col.R, col.G, col.B, col.A = 0, 0, 0, 0
	} else if colorCube {
		if (num.IsEveni(x) && num.IsEveni(y)) || ((z > 0) && num.IsEveni(z)) {
			col.R, col.G, col.B, col.A = uint8(x/2), uint8(y/2), uint8(z/2), 255
		} else {
			col.R, col.G, col.B, col.A = uint8(x), uint8(y), uint8(z), 255
		}
	} else {
		me.voxel = Scene[x][y][z]
		if me.voxel.A >= 1 {
			if correctAlpha {
				me.mixCol(col, &me.voxel, col)
			} else {
				col.R = mixRGB(col.R, me.voxel.R, col.A, me.voxel.A) // num.Mixb(me.voxel.R, me.voxel.A, col.R)
				col.G = mixRGB(col.G, me.voxel.G, col.A, me.voxel.A) // num.Mixb(me.voxel.G, me.voxel.A, col.G)
				col.B = mixRGB(col.B, me.voxel.B, col.A, me.voxel.A) // num.Mixb(me.voxel.B, me.voxel.A, col.B)
				col.A = mixA(col.A, me.voxel.A)                      // num.Mixb(1, col.A, me.voxel.A)
			}
		}
	}
}
Example #23
0
func main() {
	in := flag.String("i", "none", "input file")
	out := flag.String("o", "out.png", "output file")
	flag.Parse()
	if *in == "none" {
		return
	}
	bin := read(*in)
	binLength := len(bin)
	width := 384
	height := len(bin) / width
	rect := image.Rect(0, 0, width, height)

	img := image.NewRGBA(rect)

	p := 0
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			var c color.RGBA
			for addr := p; addr < p+3 && addr < binLength; addr++ {
				if addr%3 == 0 {
					c.R = uint8(bin[addr])
				} else if addr%3 == 1 {
					c.G = uint8(bin[addr])
				} else if addr%3 == 2 {
					c.B = uint8(bin[addr])
				}
				c.A = 0xff
			}
			p += 3
			img.Set(x, y, c)
		}
	}
	f, _ := os.OpenFile(*out, os.O_CREATE|os.O_WRONLY, 0666)
	png.Encode(f, img)
}
Example #24
0
func featurize(orig image.Image) image.Image {

	// deviation range
	color_dev := uint16(20 << 8)
	feature_dev := 4

	bounds := orig.Bounds()

	fmt.Println(bounds)

	// initialize the array of pixels traversed
	ex := make([][]bool, bounds.Max.X+1)
	for i := 0; i < bounds.Max.X+1; i++ {
		ex[i] = make([]bool, bounds.Max.Y+1)
	}

	// array of features
	// feature is an array of arrays [x,y]
	var features [][][2]int
	feature_i := 0

	// recursively investigate all neighbors of supplied pixel
	// and build feature arrays
	// some shenanigans to make anonymous functions recurisively callable
	var discover func(x int, y int)
	discover = func(x int, y int) {

		// add this pixel to the current feature
		features[feature_i] = append(features[feature_i], [2]int{x, y})
		// fmt.Println(x,y)
		ex[x][y] = true

		// grab the rgb for the supplied pixel
		_r, _g, _b, _ := orig.At(x, y).RGBA()

		for i := -1; i < 2; i++ {
			for j := -1; j < 2; j++ {
				xx, yy := x+i, y+j
				// check if it's within our bounds and if it's been processed already
				if xx < 0 || yy < 0 || xx > bounds.Max.X || yy > bounds.Max.Y || ex[xx][yy] == true {
					continue
				}
				rt, gt, bt, _ := orig.At(xx, yy).RGBA()
				// check the color range against our deviation spec
				if uint16(rt-_r) > color_dev || uint16(gt-_g) > color_dev || uint16(bt-_b) > color_dev {
					continue
				}
				discover(xx, yy)
			}
		}

	}

	// run through each pixel and build features
	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {

			// skip if already processed
			if ex[x][y] == true {
				continue
			}

			// fmt.Println(x,y)
			features = append(features, [][2]int{})
			discover(x, y)
			feature_i++
		}
	}

	newm := image.NewRGBA(bounds)
	c := new(color.RGBA)
	c.A = 255

	for f := 0; f < len(features); f++ {

		// if the feature is large enough
		// average all pixel colors in it
		// and set all pixels to that color
		if len(features[f]) > feature_dev {
			var r, g, b, ct uint64

			for p := 0; p < len(features[f]); p++ {
				rt, gt, bt, _ := orig.At(features[f][p][0], features[f][p][1]).RGBA()

				r += uint64(rt)
				g += uint64(gt)
				b += uint64(bt)
				ct++
			}
			c.R = uint8((r / ct) >> 8)
			c.G = uint8((g / ct) >> 8)
			c.B = uint8((b / ct) >> 8)

			for p := 0; p < len(features[f]); p++ {
				newm.Set(features[f][p][0], features[f][p][1], c)
			}
		} else {
			// write the pixel out as-is
			for p := 0; p < len(features[f]); p++ {
				r, g, b, _ := orig.At(features[f][p][0], features[f][p][1]).RGBA()
				c.R = uint8(r >> 8)
				c.G = uint8(g >> 8)
				c.B = uint8(b >> 8)
				newm.Set(features[f][p][0], features[f][p][1], c)
			}
		}
	}

	return newm
}
Example #25
0
func main() {

	flag.Parse()

	// Set initial values.

	shades_per_iteration = float64(max_color) / float64(*max_iterations)

	var (
		mset_x_total float64 = 3.5
		mset_y_total float64 = 2.0
	)

	mset_x_min := *mset_x_ctr - (mset_x_total / 2)
	mset_x_max := *mset_x_ctr + (mset_x_total / 2)
	mset_y_min := *mset_y_ctr - (mset_y_total / 2)
	mset_y_max := *mset_y_ctr + (mset_y_total / 2)

	// Set coordinates according to xoom factor.
	mset_y_total = (mset_y_max - mset_y_min) / *zoom
	mset_x_total = (mset_x_max - mset_x_min) / *zoom
	mset_x_min = *mset_x_ctr - (mset_x_total / 2)
	mset_x_max = *mset_x_ctr + (mset_x_total / 2)
	mset_y_min = *mset_y_ctr - (mset_y_total / 2)
	mset_y_max = *mset_y_ctr + (mset_y_total / 2)

	mset_ratio := mset_x_total / mset_y_total
	img_ratio := float64(*img_width) / float64(*img_height)

	if mset_ratio > img_ratio {
		// The image is taller than the default mandelbrot set.
		// Therefore, the limiting dimension is the height of the mandelbrot set.
		// Don't touch the Y figures.

		// Reset the X limits.
		mset_y_total = mset_y_max - mset_y_min
		mset_x_total = mset_y_total * img_ratio
		mset_x_min = *mset_x_ctr - (mset_x_total / 2)
		mset_x_max = *mset_x_ctr + (mset_x_total / 2)

	} else {
		// The image is flatter than the default mandelbrot set.
		// Therefore, the limiting dimension is the width of the mandelbrot set.
		// Don't touch the X figures.

		// Reset the Y limits.
		mset_x_total = mset_x_max - mset_x_min
		mset_y_total = mset_x_total / img_ratio
		mset_y_min = *mset_y_ctr - (mset_y_total / 2)
		mset_y_max = *mset_y_ctr + (mset_y_total / 2)
	}

	// Set slope of conversion lines.
	// m = rise/run
	m_x = mset_x_total / float64(*img_width)
	m_y = mset_y_total / float64(*img_height)
	b_x = mset_x_min
	b_y = mset_y_min

	img := image.NewRGBA(image.Rect(0, 0, *img_width, *img_height))
	//	img := image.NewGray16(image.Rect(0, 0, *img_width, *img_height))
	//	img := image.NewGray(image.Rect(0, 0, *img_width, *img_height))

	var (
		c     int64
		c_max int64 = 0
		clr   color.RGBA
		//				clr color.Gray16
		//		clr color.Gray
		//		i     int64
		i_max int64 = 0
		mpt   MPT
	)

	// mpt = new(MPT)

	for x := 0; x < *img_width; x++ {
		log.Printf("Percent Complete: %.1f", float64(x)/float64(*img_width)*100)
		for y := 0; y < *img_height; y++ {

			x_, y_ := getCoord(x, y)

			mpt.X0 = x_
			mpt.Y0 = y_
			mpt.X = 0
			mpt.Y = 0
			mpt.N = 0

			mpt.iterate()

			factor_iterations := float64(mpt.N) / float64(*max_iterations) // This is a decimal revealing the scale based on iterations.
			factor_radius := math.Log2(mpt.R) / 2

			c = int64((factor_iterations + factor_radius) * float64(*max_iterations) * shades_per_iteration)

			// c = max_color - c

			clr.G = uint8(c)
			clr.B = uint8(c >> 8)
			clr.R = uint8(c >> 16)
			clr.A = 255

			//			log.Printf("C: %b\n", c)
			//			log.Printf("R: %b\n", color.R)
			//			log.Printf("G: %b\n", color.G)
			//			log.Printf("B: %b\n", color.B)

			//			clr.Y = uint8(c)

			// The golange image is inverted on the y-axis compared to typical cartesian systems.
			img.Set(x, *img_height-y, clr)

		}
	}

	log.Printf("img_width: %d\n", *img_width)
	log.Printf("img_height: %d\n", *img_height)
	log.Printf("mset_x_min: %0.2f\n", mset_x_min)
	log.Printf("mset_x_max: %0.2f\n", mset_x_max)
	log.Printf("mset_x_total: %0.2f\n", mset_x_total)
	log.Printf("mset_y_min: %0.2f\n", mset_y_min)
	log.Printf("mset_y_max: %0.2f\n", mset_y_max)
	log.Printf("mset_y_total: %0.2f\n", mset_y_total)
	log.Printf("m_x: %0.8f\n", m_x)
	log.Printf("m_y: %0.8f\n", m_y)

	log.Printf("i_max: %d\n", i_max)
	log.Printf("c_max: %d\n", c_max)

	log.Println("Encoding image.")
	buffer := new(bytes.Buffer)
	if err := png.Encode(buffer, img); err != nil {
		log.Fatal(err.Error())
	}
	log.Println("Writing image.")
	if err := ioutil.WriteFile(fmt.Sprintf("/Users/jackman/Pictures/mandelbrot(%.4f,%.4f)z%.1f[%dx%dz]x%d.png", *mset_x_ctr, *mset_y_ctr, *zoom, *img_width, *img_height, *max_iterations), buffer.Bytes(), 0644); err != nil {
		log.Fatal(err.Error())
	}
}
Example #26
0
// Find returns the dominant color in img.
func Find(img image.Image) color.RGBA {
	// Shrink image for faster processing.
	img = resize.Thumbnail(resizeTo, resizeTo, img, resize.NearestNeighbor)

	bounds := img.Bounds()
	width, height := bounds.Dx(), bounds.Dy()
	rnd := rand.New(rand.NewSource(0))
	randomPoint := func() (x, y int) {
		x = bounds.Min.X + rnd.Intn(width)
		y = bounds.Min.Y + rnd.Intn(height)
		return
	}
	// Pick a starting point for each cluster.
	clusters := make(kMeanClusterGroup, 0, nCluster)
	for i := 0; i < nCluster; i++ {
		// Try up to 10 times to find a unique color. If no unique color can be
		// found, destroy this cluster.
		colorUnique := false
		for j := 0; j < maxSample; j++ {
			ri, gi, bi, a := img.At(randomPoint()).RGBA()
			// Ignore transparent pixels.
			if a == 0 {
				continue
			}
			r, g, b := uint8(ri/255), uint8(gi/255), uint8(bi/255)
			// Check to see if we have seen this color before.
			colorUnique = !clusters.ContainsCentroid(r, g, b)
			// If we have a unique color set the center of the cluster to
			// that color.
			if colorUnique {
				c := new(kMeanCluster)
				c.SetCentroid(r, g, b)
				clusters = append(clusters, c)
				break
			}
		}
		if !colorUnique {
			break
		}
	}
	convergence := false
	for i := 0; i < nIterations && !convergence && len(clusters) != 0; i++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
				ri, gi, bi, a := img.At(x, y).RGBA()
				// Ignore transparent pixels.
				if a == 0 {
					continue
				}
				r, g, b := uint8(ri/255), uint8(gi/255), uint8(bi/255)
				// Figure out which cluster this color is closest to in RGB space.
				closest := clusters.Closest(r, g, b)
				closest.AddPoint(r, g, b)
			}
		}
		// Calculate the new cluster centers and see if we've converged or not.
		convergence = true
		for _, c := range clusters {
			convergence = convergence && c.CompareCentroidWithAggregate()
			c.RecomputeCentroid()
		}
	}
	// Sort the clusters by population so we can tell what the most popular
	// color is.
	sort.Sort(byWeight(clusters))
	// Loop through the clusters to figure out which cluster has an appropriate
	// color. Skip any that are too bright/dark and go in order of weight.
	var col color.RGBA
	for i, c := range clusters {
		r, g, b := c.Centroid()
		// Sum the RGB components to determine if the color is too bright or too dark.
		var summedColor uint16 = uint16(r) + uint16(g) + uint16(b)

		if summedColor < maxBrightness && summedColor > minDarkness {
			// If we found a valid color just set it and break. We don't want to
			// check the other ones.
			col.R = r
			col.G = g
			col.B = b
			col.A = 0xFF
			break
		} else if i == 0 {
			// We haven't found a valid color, but we are at the first color so
			// set the color anyway to make sure we at least have a value here.
			col.R = r
			col.G = g
			col.B = b
			col.A = 0xFF
		}
	}
	return col
}