Beispiel #1
0
func NewRGB48FromImage(m image.Image) *RGB48 {
	if m, ok := m.(*RGB48); ok {
		return m
	}

	// try `Image` interface
	if x, ok := m.(Image); ok {
		// try original type
		if m, ok := x.BaseType().(*RGB48); ok {
			return m
		}
		// create new image with `x.Pix()`
		if x.Channels() == 3 && x.Depth() == reflect.Uint16 {
			return new(RGB48).Init(x.Pix(), x.Stride(), x.Rect())
		}
	}

	// convert to RGB48
	b := m.Bounds()
	rgb48 := NewRGB48(b)
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			pr, pg, pb, _ := m.At(x, y).RGBA()
			rgb48.SetRGB48(x, y, RGB48Color{
				uint16(pr),
				uint16(pg),
				uint16(pb),
			})
		}
	}
	return rgb48
}
Beispiel #2
0
func histogram(img image.Image, bins int) []int {
	mi, _, _ := getMin(img)
	ma, _, _ := getMax(img)

	//fmt.Printf("max and min are : %v %v\n", mi, ma)
	bounds := img.Bounds()
	var h []int
	h = make([]int, bins, bins)

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r, g, b, _ := img.At(x, y).RGBA()
			a := 0.2125*float64(r) + 0.7154*float64(g) + 0.0721*float64(b)
			idx := int(math.Floor((a - mi) / (ma - mi) * (float64(bins) - 1.0)))
			if idx < 0 {
				idx = 0
			}
			if idx >= bins {
				idx = bins - 1
			}
			h[idx]++
		}
	}
	return h
}
Beispiel #3
0
// encodeRGB64Data writes image data as 16-bit samples.
func encodeRGB64Data(w io.Writer, img image.Image, opts *EncodeOptions) error {
	// In the background, write each 16-bit color sample into a channel.
	rect := img.Bounds()
	width := rect.Max.X - rect.Min.X
	samples := make(chan uint16, width*3)
	go func() {
		cm := npcolor.RGBM64Model{M: opts.MaxValue}
		for y := rect.Min.Y; y < rect.Max.Y; y++ {
			for x := rect.Min.X; x < rect.Max.X; x++ {
				c := cm.Convert(img.At(x, y)).(npcolor.RGBM64)
				samples <- c.R
				samples <- c.G
				samples <- c.B
			}
		}
		close(samples)
	}()

	// In the foreground, consume color samples and write them to the image
	// file.
	if opts.Plain {
		return writePlainData(w, samples)
	} else {
		return writeRawData(w, samples, 2)
	}
}
Beispiel #4
0
// convert an image into ASCII!
// watch out, this might be painfully slow...
func Convert(m image.Image, p []*TextColor) *Image {

	c := NewPalette(p)

	// create image of correct size
	bounds := m.Bounds()
	s := bounds.Size()
	img := NewImage(uint(s.X),
		uint(s.Y))

	// dereference for slice manipulation
	grid := *img
	var wg sync.WaitGroup
	for y := range grid {
		wg.Add(1)
		go func(r []*TextColor, y int) {
			for x := range r {
				r[x] = c.Convert(m.At(x+bounds.Min.X, y+bounds.Min.Y)).(*TextColor)
			}
			wg.Done()
		}(grid[y], y)
	}
	wg.Wait()
	return img
}
Beispiel #5
0
// DifferenceHash computes the difference hash of an image.
func DifferenceHash(source image.Image) uint64 {

	const sw, sh, hw, hh = 9, 8, 8, 8

	// Convert the image to the grayscale colourspace.
	bounds := source.Bounds()
	width, height := bounds.Max.X, bounds.Max.Y
	gray := image.NewGray(source.Bounds())
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			gray.Set(x, y, source.At(x, y))
		}
	}

	// Resize the image.
	shrunk := resize.Resize(sw, sh, gray, resize.NearestNeighbor).(*image.Gray)

	// Compute the difference hash.
	var hash uint64
	for y := 0; y < hh; y++ {
		for x := 0; x < hw; x++ {
			if shrunk.GrayAt(x, y).Y < shrunk.GrayAt(x+1, y).Y {
				hash |= 1 << uint64((y*hw)+x)
			}
		}
	}
	return hash

}
func ReadShadowData(im image.Image) (b []byte, err error) {
	head, err := ReadShadowHeader(im)
	if err != nil {
		return nil, err
	}
	length := int(ReadShadowLength(head))
	var bk []byte = make([]byte, length*8)
	b = make([]byte, length)
	_, err = SetImage(im, func(index, x, y int, in, out image.Image) {
		if index >= 64 && index < length*8+64 {
			R := readRGBAColor(im.At(x, y)).R
			bk[index-64] = uint8(R & 1)
		}
	})
	var bb [8]byte
	var bs []byte
	for i := 0; i < length; i++ {
		bs = bk[8*i : 8*(i+1)]
		for j := 0; j < 8; j++ {
			bb[j] = bs[j]
		}
		b[i] = Bits2Byte(bb)
	}
	return
}
Beispiel #7
0
func (w *walker) IsVertex(cell image.Point, img image.Image) bool {
	// a point is a vertex iff it has 4 'different' neightbors, this includes diagonal
	count := 0
	x := cell.X
	y := cell.Y
	myColor := color.White
	for i := -1; i < 2; i++ {
		for j := -1; j < 2; j++ {
			Maxsize := img.Bounds().Max
			Minsize := img.Bounds().Min
			if x+i > Maxsize.X || x+i < Minsize.X {
				count++
			}
			if y+i > Maxsize.Y || y+i < Minsize.Y {
				count++
			}
			if sameColor(myColor, img.At(x+i, y+j)) {
				count++
			}
		}
	}
	if count >= 4 {
		return true
	}
	return false
}
Beispiel #8
0
func GlRgba(img image.Image, rot matrix23) []gl.GLubyte {
	bounds := img.Bounds()
	sizeX := bounds.Size().X
	sizeY := bounds.Size().Y
	data := make([]gl.GLubyte, sizeX*sizeY*4)
	// x and y are in the source frame.
	// X and Y are in the destination frame.
	// x and y are not garanteed to start at 0 because that is how images work
	// in Go.  However, X and Y are because my output buffer is built the way
	// I want it.
	Y := -1
	for y := bounds.Max.Y - 1; y >= bounds.Min.Y; y-- {
		Y++
		X := -1
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			X++
			color := img.At(x, y)
			r, g, b, a := color.RGBA()
			rX, rY := rot.mul(X, Y)
			i := (rY*sizeX + rX) * 4 // Assumes square texture.
			//fmt.Println(X, Y, rX, rY, i)
			data[i+0] = gl.GLubyte(r >> 8)
			data[i+1] = gl.GLubyte(g >> 8)
			data[i+2] = gl.GLubyte(b >> 8)
			data[i+3] = gl.GLubyte(a >> 8)
		}
	}
	return data
}
Beispiel #9
0
// EachColorInRectangle is a helper function for working on a part of an image.
func EachColorInRectangle(img image.Image, b image.Rectangle, f func(c color.Color)) {
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			f(img.At(x, y))
		}
	}
}
Beispiel #10
0
// thanks to IonicaBizau/image-to-ascii for algorithm
func Convert(img image.Image) (str string) {
	var buffer bytes.Buffer
	size := img.Bounds().Max
	pixels := ".,:;i1tfLCG08@"
	precision := (255 * 4) / (len(pixels) - 1)

	// ansi color end constant
	reset := ansi.ColorCode("reset")

	for y := 0; y < size.Y; y += 1 {
		for x := 0; x < size.X; x += 1 {
			r, g, b, a := img.At(x, y).RGBA()
			sum := r>>8 + g>>8 + b>>8 + a>>8
			pixel := pixels[int(sum)/precision]
			// find the closest ansi color code
			code := x256.ClosestCode(uint8(r>>8), uint8(g>>8), uint8(b>>8))
			/// get the ansi color code
			color := ansi.ColorCode(strconv.Itoa(code))

			// write the pixel
			buffer.WriteString(color)
			buffer.WriteString(string(pixel))
			buffer.WriteString(reset)
		}
		buffer.WriteString("\n")
	}

	return buffer.String()
}
Beispiel #11
0
func Crop(img image.Image, width int, height int, padding int) (fimg draw.Image, err error) {
	// For now assume top left is bg color
	// future maybe avg outer rows of pixels
	bgcolor := img.At(img.Bounds().Min.X, img.Bounds().Min.Y)
	logoh, logow := height-2*padding, width-2*padding
	logorat := float32(logow) / float32(logoh)

	interior := findLogo(img, bgcolor)
	interior.Max = interior.Max.Add(image.Pt(1, 1))

	center := func(rect image.Rectangle) image.Point {
		return image.Point{(rect.Max.X - rect.Min.X) / 2, (rect.Max.Y - rect.Min.Y) / 2}
	}
	fimg = image.NewRGBA(image.Rect(0, 0, width, height))

	rc := center(fimg.Bounds())
	origrat := float32(interior.Dx()) / float32(interior.Dy())

	if logorat > origrat {
		logow = int(origrat * float32(logoh))
	} else {
		logoh = int(float32(logow) / origrat)
	}
	logoimg := Resize(img, interior, logow, logoh)

	logorect := image.Rect(0, 0, logoimg.Bounds().Dx(), logoimg.Bounds().Dy())
	logorect = logorect.Add(rc.Sub(image.Pt(logorect.Dx()/2, logorect.Dy()/2)))

	draw.Draw(fimg, fimg.Bounds(), &image.Uniform{bgcolor}, image.ZP, draw.Src)
	draw.Draw(fimg, logorect, logoimg, image.ZP, draw.Src)
	return
}
Beispiel #12
0
func encodePPM(w io.Writer, m image.Image, maxvalue int) error {
	b := m.Bounds()
	// write header
	_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", b.Dx(), b.Dy(), maxvalue)
	if err != nil {
		return err
	}

	// write raster
	cm := color.RGBAModel
	row := make([]uint8, b.Dx()*3)
	for y := b.Min.Y; y < b.Max.Y; y++ {
		i := 0
		for x := b.Min.X; x < b.Max.X; x++ {
			c := cm.Convert(m.At(x, y)).(color.RGBA)
			row[i] = c.R
			row[i+1] = c.G
			row[i+2] = c.B
			i += 3
		}
		if _, err := w.Write(row); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #13
0
/*
 * NewWorld creates a brand new world.
 *
 * It loads the map from the provided Surviveler Package and initializes the
 * world representation from it.
 */
func NewWorld(img image.Image, gridScale float32) (*World, error) {
	bounds := img.Bounds()
	w := World{
		GridWidth:  bounds.Max.X,
		GridHeight: bounds.Max.Y,
		Width:      float32(bounds.Max.X) / gridScale,
		Height:     float32(bounds.Max.Y) / gridScale,
		GridScale:  gridScale,
		Entities:   make(map[uint32]TileList),
	}
	log.WithField("world", w).Info("Building world")

	// allocate tiles
	var kind TileKind
	w.Grid = make([]Tile, bounds.Max.X*bounds.Max.Y)
	for x := bounds.Min.X; x < bounds.Max.X; x++ {
		for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
			r, _, _, _ := img.At(x, y).RGBA()
			if r == 0 {
				kind = KindNotWalkable
			} else {
				kind = KindWalkable
			}
			w.Grid[x+y*w.GridWidth] = NewTile(kind, &w, x, y)
		}
	}
	return &w, nil
}
Beispiel #14
0
func nearestNeighbour(im image.Image, scalex float32, scaley float32) (imageng, os.Error) {
	if scalex > 1 && scaley > 1 {
		ws := im.Bounds().Dx()
		hs := im.Bounds().Dy()
		wd := int(scalex * float32(ws))
		hd := int(scaley * float32(hs))

		scaled := imgType(im, wd, hd)

		var xs, ys, dx, dy, neighbour, row int
		ys = 0
		row = 0
		dy = int(float32(ys+1)*scaley) / 2
		for y := 0; y < hd; y++ {
			if abs(y-row) > dy {
				ys++
				row = int(float32(ys) * scaley)
				dy = (int(float32(ys+1)*scaley) - row) / 2
			}
			xs = 0
			neighbour = 0
			dx = int(float32(xs+1)*scalex) / 2
			for x := 0; x < wd; x++ {
				if abs(x-neighbour) > dx {
					xs++
					neighbour = int(float32(xs) * scalex)
					dx = (int(float32(xs+1)*scalex) - neighbour) / 2
				}
				scaled.Set(x, y, im.At(xs, ys))
			}
		}
		return scaled, nil
	}
	return nil, os.NewError("no scaling down")
}
Beispiel #15
0
Datei: main.go Projekt: jf/gwp
// cut out the image and return individual channels with image.Image
// no encoding of JPEG
func cut(original image.Image, db *map[string][3]float64, tileSize, x1, y1, x2, y2 int) <-chan image.Image {
	c := make(chan image.Image)
	sp := image.Point{0, 0}
	go func() {
		newimage := image.NewNRGBA(image.Rect(x1, y1, x2, y2))
		for y := y1; y < y2; y = y + tileSize {
			for x := x1; x < x2; x = x + tileSize {
				r, g, b, _ := original.At(x, y).RGBA()
				color := [3]float64{float64(r), float64(g), float64(b)}
				nearest := nearest(color, db)
				file, err := os.Open(nearest)
				if err == nil {
					img, _, err := image.Decode(file)
					if err == nil {
						t := resize(img, tileSize)
						tile := t.SubImage(t.Bounds())
						tileBounds := image.Rect(x, y, x+tileSize, y+tileSize)
						draw.Draw(newimage, tileBounds, tile, sp, draw.Src)
					} else {
						fmt.Println("error in decoding nearest", err, nearest)
					}
				} else {
					fmt.Println("error opening file when creating mosaic:", nearest)
				}
				file.Close()
			}
		}
		c <- newimage.SubImage(newimage.Rect)
	}()

	return c
}
Beispiel #16
0
func Benchmark_BigResizeLanczos3(b *testing.B) {
	var m image.Image
	for i := 0; i < b.N; i++ {
		m = Resize(1000, 1000, img, Lanczos3)
	}
	m.At(0, 0)
}
Beispiel #17
0
func Crop(m image.Image, r image.Rectangle, w, h int) image.Image {
	if w < 0 || h < 0 {
		return nil
	}
	if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
		return image.NewRGBA64(image.Rect(0, 0, w, h))
	}
	curw, curh := r.Min.X, r.Min.Y

	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 := curw + x
			suby := curh + y

			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
}
func evalPixels(t *testing.T, i image.Image, p image.Point, colors []int) {
	for y := 0; y < p.Y; y++ {
		for x := 0; x < p.X; x++ {
			var er, eg, eb, ea uint32
			e := colors[p.X*y+x]
			if e == 1 {
				er = 0xffff
				eg = 0xffff
				eb = 0xffff
			} else {
				er = 0
				eg = 0
				eb = 0
			}
			ea = 0xffff

			a := i.At(u/2>>0+u*x, u/2>>0+u*y)
			ar, ag, ab, aa := a.RGBA()

			if !(isNear(er, ar) && isNear(eg, ag) && isNear(eb, ab) && isNear(ea, aa)) {
				t.Errorf(
					"wrong color at (%d, %d) expected {%d, %d, %d, %d}, but actual {%d, %d, %d, %d}",
					x, y,
					er, eg, eb, ea,
					ar, ag, ab, aa,
				)
			}
		}
	}
}
Beispiel #19
0
func generateHistogramForImage(m image.Image) [][]float64 {

	bounds := m.Bounds()
	widthPixels := int(bounds.Max.X - bounds.Min.X)
	heightPixels := int(bounds.Max.Y - bounds.Min.Y)
	histogram := make([][]float64, 3)

	for i := range histogram {
		histogram[i] = make([]float64, widthPixels)
	}

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r, g, b, _ := m.At(x, y).RGBA()
			// values should be between 0 and 1
			relR := float64(r) / 65535.0
			relG := float64(g) / 65535.0
			relB := float64(b) / 65535.0
			histogram[0][x] += relR
			histogram[1][x] += relG
			histogram[2][x] += relB
		}
	}

	// create rounded mean value for each x value
	for i, values := range histogram {
		for j := range values {
			histogram[i][j] = roundedMean(histogram[i][j], float64(heightPixels))
		}
	}

	return histogram
}
Beispiel #20
0
// Image returns a thumbnail-size version of src.
func Image(src image.Image) image.Image {
	// Compute thumbnail size, preserving aspect ratio.
	xs := src.Bounds().Size().X
	ys := src.Bounds().Size().Y
	width, height := 128, 128
	if aspect := float64(xs) / float64(ys); aspect < 1.0 {
		width = int(128 * aspect) // portrait
	} else {
		height = int(128 / aspect) // landscape
	}
	xscale := float64(xs) / float64(width)
	yscale := float64(ys) / float64(height)

	dst := image.NewRGBA(image.Rect(0, 0, width, height))

	// a very crude scaling algorithm
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			srcx := int(float64(x) * xscale)
			srcy := int(float64(y) * yscale)
			dst.Set(x, y, src.At(srcx, srcy))
		}
	}
	return dst
}
Beispiel #21
0
func (w *walker) ExploreObject(o *object, img image.Image, loc image.Point) {
	frontier := []image.Point{}
	start := loc
	myColor := o.c
	Maxsize := img.Bounds().Max
	//Minsize := img.Bounds().Min
	x := start.X
	y := start.Y

	for sameColor(myColor, img.At(x, y)) && x < Maxsize.X {
		w.explored[image.Pt(x, y)] = true
		x++
	}
	x--
	if w.IsVertex(image.Pt(x, y), img) {
		//add the vertex to the objects list
		frontier = append(frontier, image.Pt(x, y))
	}
	x = start.X
	for sameColor(myColor, img.At(x, y)) && y < Maxsize.Y {
		w.explored[image.Pt(x, y)] = true
		y++
	}
	y--
	if w.IsVertex(image.Pt(x, y), img) {
		//add the vertex to the objects list
		frontier = append(frontier, image.Pt(x, y))
	}
}
Beispiel #22
0
// pushGenericLocked is the slow path generic implementation that works on
// any image.Image concrete type and any client-requested pixel format.
// If you're lucky, you never end in this path.
func (c *Conn) pushGenericLocked(im image.Image) {
	b := im.Bounds()
	width, height := b.Dx(), b.Dy()
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			col := im.At(x, y)
			r16, g16, b16, _ := col.RGBA()
			r16 = inRange(r16, c.format.RedMax)
			g16 = inRange(g16, c.format.GreenMax)
			b16 = inRange(b16, c.format.BlueMax)
			var u32 uint32 = (r16 << c.format.RedShift) |
				(g16 << c.format.GreenShift) |
				(b16 << c.format.BlueShift)
			var v interface{}
			switch c.format.BPP {
			case 32:
				v = u32
			case 16:
				v = uint16(u32)
			case 8:
				v = uint8(u32)
			default:
				c.failf("TODO: BPP of %d", c.format.BPP)
			}
			if c.format.BigEndian != 0 {
				binary.Write(c.bw, binary.BigEndian, v)
			} else {
				binary.Write(c.bw, binary.LittleEndian, v)
			}
		}
	}
}
Beispiel #23
0
// TODO use multiple channels to store edge intersections
func (sdf *SDF) calc(m image.Image) {
	max := dist(0, 0, sdf.pad, sdf.pad) - 1
	b := m.Bounds()
	// TODO this space could probably be traversed better
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			_, _, _, ma := m.At(x, y).RGBA()

			c := nearest(x, y, m.(*image.NRGBA).SubImage(image.Rect(x-sdf.pad, y-sdf.pad, x+sdf.pad, y+sdf.pad)))
			if c == 0xFF {
				// check if pixel is inside as a center of opposing edges
				if ma != 0 {
					sdf.dst.Set(x, y, color.RGBA{A: 0xFF})
				}
				continue
			}

			// return from nearest is always >= 1
			// decrement so that c/max returns a unit value inclusive of zero
			c--

			n := 0xFF * (1 - (float64(c) / float64(max)))
			if ma != 0 { // inside edge
				sdf.dst.Set(x, y, color.RGBA{A: 0xFF - uint8(n/2)})
			} else { // outside edge
				step := float64(0xFF) / float64(max)
				if n = n - step; n < 0 {
					n = 0
				}
				sdf.dst.Set(x, y, color.RGBA{A: uint8(n / 2)})
			}
		}
	}
}
Beispiel #24
0
func parseImgBoundary(img image.Image) {
	minX, maxX := img.Bounds().Min.X, img.Bounds().Max.X
	minY, maxY := img.Bounds().Min.Y, img.Bounds().Max.Y
	for i := minX; i < maxX; i++ {
		for j := minY; j < maxY; j++ {
			_, _, _, a := img.At(i, j).RGBA()
			if a != 0 {
				if boundary.Empty() && boundary.Min.X == -1 {
					boundary = image.Rect(i, j, i, j)
				} else {
					_p := image.Point{i, j}
					if !_p.In(boundary) {
						boundary = boundary.Union(image.Rect(i, j, i, j))
					}
				}
			}
		}
	}

	// Should Make the midline of boundary and the img
	l := boundary.Min.X
	r := imageW - boundary.Max.X
	if l > r {
		boundary.Min.X = r
	} else if l < r {
		boundary.Max.X = imageW - l
	}
}
/**
 * Returns a new graph that represents the image img. The graph will be either
 * a King's grph or a Grid graph. It will compute the edge weights using the
 * provided function weight.
 */
func FromImage(img image.Image, weight WeightFn, graphType GraphType) *Graph {
	g := new(Graph)
	g.height = img.Bounds().Max.Y
	g.width = img.Bounds().Max.X
	g.graphType = graphType
	g.edges = make(EdgeList, 0, g.TotalEdges())
	size := 4
	if graphType == KINGSGRAPH {
		size = 8
	}
	g.weights = make([][]float64, g.TotalVertices(), g.TotalVertices())

	for y := 0; y < g.height; y++ {
		for x := 0; x < g.width; x++ {
			p := x + y*g.width
			pixel := Pixel{X: x, Y: y, Color: img.At(x, y)}
			g.weights[p] = make([]float64, size/2, size/2)
			for n := range g.Neighbors(p) {
				x2, y2 := n%g.width, n/g.width
				pixel2 := Pixel{X: x2, Y: x2, Color: img.At(x2, y2)}
				w := weight(pixel, pixel2)
				g.edges = append(g.edges, Edge{u: p, v: n, weight: w})
				g.weights[p][g.weightIndex(p, n)] = w
			}
		}
	}
	return g
}
Beispiel #26
0
// Return a VImageBuffer of the given image. The memory may or may not
// be shared depending on the format. Also return the format of the returned
// image. (e.g. argb8888, rgba8888, 8, ...)
func VImageBufferFromImage(img image.Image) (*VImageBuffer, string) {
	switch m := img.(type) {
	case *image.Gray:
		return &VImageBuffer{Width: m.Bounds().Dx(), Height: m.Bounds().Dy(), RowBytes: m.Stride, Data: m.Pix}, "8"
	case *image.RGBA:
		return &VImageBuffer{Width: m.Bounds().Dx(), Height: m.Bounds().Dy(), RowBytes: m.Stride, Data: m.Pix}, "rgba8888"
	}

	b := img.Bounds()
	w := b.Dx()
	h := b.Dy()
	data := make([]byte, w*h*4)
	dataOffset := 0
	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			c := img.At(x+b.Min.X, y+b.Min.Y)
			r, g, b, a := c.RGBA()
			data[dataOffset] = uint8(a >> 8)
			data[dataOffset+1] = uint8(r >> 8)
			data[dataOffset+2] = uint8(g >> 8)
			data[dataOffset+3] = uint8(b >> 8)
			dataOffset += 4
		}
	}
	return &VImageBuffer{Width: w, Height: h, RowBytes: w * 4, Data: data}, "argb8888"
}
Beispiel #27
0
// toRGBA translates the given image to RGBA format if necessary.
// Optionally scales it by the given amount.
func toRGBA(src image.Image, scale int) *image.RGBA {
	if scale < 1 {
		scale = 1
	}

	dst, ok := src.(*image.RGBA)
	if ok && scale == 1 {
		return dst
	}

	// Scale image to match new size.
	ib := src.Bounds()
	rect := image.Rect(0, 0, ib.Dx()*scale, ib.Dy()*scale)

	if !ok {
		// Image is not RGBA, so we create it.
		dst = image.NewRGBA(rect)
	}

	for sy := 0; sy < ib.Dy(); sy++ {
		for sx := 0; sx < ib.Dx(); sx++ {
			dx := sx * scale
			dy := sy * scale
			pixel := src.At(sx, sy)

			for scy := 0; scy < scale; scy++ {
				for scx := 0; scx < scale; scx++ {
					dst.Set(dx+scx, dy+scy, pixel)
				}
			}
		}
	}

	return dst
}
Beispiel #28
0
func find_projection_in_line(scan image.Image, y_pix int, est_location int) int {
	enter_white, exit_white := 0, 0
	var min_x, max_x int

	if est_location == -1 || est_location < expected_x_deviation || est_location > (image_size_x-expected_x_deviation) {
		min_x, max_x = 0, image_size_x
	} else {
		min_x, max_x = est_location-expected_x_deviation, est_location+expected_x_deviation
	}

	for x := min_x; x < max_x; x++ {
		color := scan.At(x, y_pix)
		r, g, b, _ := color.RGBA()
		if is_white(r, g, b) {
			enter_white = x
			break
		}
	}

	for x := enter_white; x < max_x; x++ {
		color := scan.At(x, y_pix)
		r, g, b, _ := color.RGBA()
		if !is_white(r, g, b) {
			exit_white = x - 1
			break
		}
	}

	if enter_white != 0 && exit_white != 0 && (exit_white-enter_white) < maximum_line_size {
		return int((enter_white + exit_white) / 2)
	}

	return -99999
}
func hough(im image.Image, ntx, mry int) draw.Image {
	nimx := im.Bounds().Max.X
	mimy := im.Bounds().Max.Y
	mry = int(mry/2) * 2
	him := image.NewGray(image.Rect(0, 0, ntx, mry))
	draw.Draw(him, him.Bounds(), image.NewUniform(color.White),
		image.ZP, draw.Src)

	rmax := math.Hypot(float64(nimx), float64(mimy))
	dr := rmax / float64(mry/2)
	dth := math.Pi / float64(ntx)

	for jx := 0; jx < nimx; jx++ {
		for iy := 0; iy < mimy; iy++ {
			col := color.GrayModel.Convert(im.At(jx, iy)).(color.Gray)
			if col.Y == 255 {
				continue
			}
			for jtx := 0; jtx < ntx; jtx++ {
				th := dth * float64(jtx)
				r := float64(jx)*math.Cos(th) + float64(iy)*math.Sin(th)
				iry := mry/2 - int(math.Floor(r/dr+.5))
				col = him.At(jtx, iry).(color.Gray)
				if col.Y > 0 {
					col.Y--
					him.SetGray(jtx, iry, col)
				}
			}
		}
	}
	return him
}
Beispiel #30
0
// 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.Image {
	if w < 0 || h < 0 {
		return nil
	}
	if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 {
		return image.NewRGBA64(image.Rect(0, 0, w, h))
	}
	img := image.NewRGBA(image.Rect(0, 0, w, h))
	xStep := float64(r.Dx()) / float64(w)
	yStep := float64(r.Dy()) / float64(h)
	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			xSrc := int(float64(r.Min.X) + float64(x)*xStep)
			ySrc := int(float64(r.Min.Y) + float64(y)*yStep)
			r, g, b, a := m.At(xSrc, ySrc).RGBA()
			img.SetRGBA(x, y, color.RGBA{
				R: uint8(r >> 8),
				G: uint8(g >> 8),
				B: uint8(b >> 8),
				A: uint8(a >> 8),
			})
		}
	}
	return img
}