Beispiel #1
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 #2
0
func (e *engine) LoadTexture(src image.Image) (sprite.Texture, error) {
	b := src.Bounds()
	t := &texture{glutil.NewImage(b.Dx(), b.Dy()), b}
	t.Upload(b, src)
	// TODO: set "glImage.Pix = nil"?? We don't need the CPU-side image any more.
	return t, nil
}
Beispiel #3
0
// Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given
// options. Default parameters are used if a nil *Options is passed.
func Encode(w io.Writer, m image.Image, o *Options) error {
	b := m.Bounds()
	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 {
		return errors.New("jpeg: image is too large to encode")
	}
	var e encoder
	if ww, ok := w.(writer); ok {
		e.w = ww
	} else {
		e.w = bufio.NewWriter(w)
	}
	// Clip quality to [1, 100].
	quality := DefaultQuality
	if o != nil {
		quality = o.Quality
		if quality < 1 {
			quality = 1
		} else if quality > 100 {
			quality = 100
		}
	}
	// Convert from a quality rating to a scaling factor.
	var scale int
	if quality < 50 {
		scale = 5000 / quality
	} else {
		scale = 200 - quality*2
	}
	// Initialize the quantization tables.
	for i := range e.quant {
		for j := range e.quant[i] {
			x := int(unscaledQuant[i][j])
			x = (x*scale + 50) / 100
			if x < 1 {
				x = 1
			} else if x > 255 {
				x = 255
			}
			e.quant[i][j] = uint8(x)
		}
	}
	// Write the Start Of Image marker.
	e.buf[0] = 0xff
	e.buf[1] = 0xd8
	e.write(e.buf[:2])
	// Write the quantization tables.
	e.writeDQT()
	// Write the image dimensions.
	e.writeSOF0(b.Size())
	// Write the Huffman tables.
	e.writeDHT()
	// Write the image data.
	e.writeSOS(m)
	// Write the End Of Image marker.
	e.buf[0] = 0xff
	e.buf[1] = 0xd9
	e.write(e.buf[:2])
	e.flush()
	return e.err
}
Beispiel #4
0
func edgeDetect(i image.Image, o image.Image) {
	w := i.Bounds().Size().X
	h := i.Bounds().Size().Y
	cies := makeCies(i)

	for y := 0; y < h; y++ {
		for x := 0; x < w; x++ {
			var lightness float64

			if x == 0 || x >= w-1 || y == 0 || y >= h-1 {
				//lightness = cie((*i).At(x, y))
				lightness = 0
			} else {
				lightness = cies[y*w+x]*4.0 -
					cies[x+(y-1)*w] -
					cies[x-1+y*w] -
					cies[x+1+y*w] -
					cies[x+(y+1)*w]
			}

			nc := color.RGBA{0, uint8(bounds(lightness)), 0, 255}
			o.(*image.RGBA).Set(x, y, nc)
		}
	}
}
Beispiel #5
0
func noise(src image.Image, dst image.RGBA) error {
	// get the boundary box of the original image
	orig := src.Bounds()

	// copy it into the destination image buffer
	for x := orig.Min.X; x < orig.Max.X; x++ {
		for y := orig.Min.Y; y < orig.Max.Y; y++ {
			dst.Set(x, y, src.At(x, y))
		}
	}

	// shift some colors
	numToMod := (orig.Max.X * orig.Max.Y) / 2
	for i := 0; i < numToMod; i++ {
		x := rand.Intn(orig.Max.X)
		y := rand.Intn(orig.Max.Y)
		if prev, ok := src.At(x, y).(color.RGBA); ok {
			prev.R += 30
			prev.B -= 30
			prev.G += 30
			dst.Set(x, y, prev)
		}
		if prev, ok := src.At(x, y).(color.YCbCr); ok {
			prev.Cr += 30
			prev.Cb -= 30
			prev.Y += 30
			dst.Set(x, y, prev)
		}
	}

	return nil

}
Beispiel #6
0
func mean(img image.Image, disk int) image.Image {
	g := gift.New(gift.Grayscale())
	g.Add(gift.Mean(disk, false)) // use square neighborhood
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)
	return (dst)
}
Beispiel #7
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 #8
0
// newIntegrals returns the integral and the squared integral.
func newIntegrals(src image.Image) (*integral, *integral) {
	b := src.Bounds()
	srcg, ok := src.(*image.Gray)
	if !ok {
		srcg = image.NewGray(b)
		draw.Draw(srcg, b, src, b.Min, draw.Src)
	}

	m := integral{
		pix:    make([]uint64, b.Max.Y*b.Max.X),
		stride: b.Max.X,
		rect:   b,
	}
	mSq := integral{
		pix:    make([]uint64, b.Max.Y*b.Max.X),
		stride: b.Max.X,
		rect:   b,
	}
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			os := (y-b.Min.Y)*srcg.Stride + x - b.Min.X
			om := (y-b.Min.Y)*m.stride + x - b.Min.X
			c := uint64(srcg.Pix[os])
			m.pix[om] = c
			mSq.pix[om] = c * c
		}
	}
	m.integrate()
	mSq.integrate()
	return &m, &mSq
}
Beispiel #9
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

}
Beispiel #10
0
func imageBytes(img image.Image) (buf *bytes.Buffer, err error) {
	var (
		bounds image.Rectangle = img.Bounds()
		rgba   *image.RGBA
		data   []byte
	)
	buf = &bytes.Buffer{}
	rgba = image.NewRGBA(bounds)
	draw.Draw(rgba, bounds, img, bounds.Min, draw.Src)
	data = make([]byte, len(rgba.Pix))
	var (
		destOffset int = len(data) - rgba.Stride
	)
	for srcOffset := 0; srcOffset < len(rgba.Pix); {
		var (
			dest   = data[destOffset : destOffset+rgba.Stride]
			source = rgba.Pix[srcOffset : srcOffset+rgba.Stride]
		)
		copy(dest, source)
		destOffset -= rgba.Stride
		srcOffset += rgba.Stride
	}
	for x := 0; x < len(data); {
		buf.WriteByte(data[x+3])
		buf.WriteByte(data[x+2])
		buf.WriteByte(data[x+1])
		buf.WriteByte(data[x+0])
		x += 4
	}
	return
}
Beispiel #11
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 #12
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 #13
0
func SizeofImage(m image.Image) int {
	if m, ok := m.(SizeofImager); ok {
		return m.SizeofImage()
	}
	if m, ok := AsMemPImage(m); ok {
		return int(unsafe.Sizeof(*m)) + len(m.XPix)
	}

	b := m.Bounds()
	switch m := m.(type) {
	case *image.Alpha:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*1
	case *image.Alpha16:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*2
	case *image.Gray:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*1
	case *image.Gray16:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*2
	case *image.NRGBA:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*4
	case *image.NRGBA64:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*8
	case *image.RGBA:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*4
	case *image.RGBA64:
		return int(unsafe.Sizeof(*m)) + b.Dx()*b.Dy()*8
	case *image.Uniform:
		return int(unsafe.Sizeof(*m))
	case *image.YCbCr:
		return int(unsafe.Sizeof(*m)) + len(m.Y) + len(m.Cb) + len(m.Cr)
	}

	// return same as RGBA64 size
	return int(unsafe.Sizeof((*image.RGBA64)(nil))) + b.Dx()*b.Dy()*8
}
Beispiel #14
0
func composite(input *gif.GIF, lgtm image.Image) (*gif.GIF, error) {
	output := gif.GIF{
		Delay:     input.Delay,
		LoopCount: input.LoopCount,
		Disposal:  input.Disposal,
		Config: image.Config{
			Width:  input.Config.Width,
			Height: input.Config.Height,
		},
	}

	x := input.Config.Width/2 - lgtm.Bounds().Dx()/2
	y := input.Config.Height/2 - lgtm.Bounds().Dy()/2

	fmt.Print("compositting frame...")

	for i, frame := range input.Image {
		fmt.Printf("%d ", i+1)

		draw.Draw(frame, frame.Bounds(), lgtm, image.Point{-x, -y}, draw.Over)
		output.Image = append(output.Image, frame)
	}

	fmt.Println("done")
	return &output, nil
}
Beispiel #15
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 #16
0
func drawPoint(point Point, dst *image.RGBA, src image.Image) {
	p := image.Point{point.X, point.Y}
	srcRect := src.Bounds()
	size := srcRect.Size()
	rect := image.Rectangle{p, p.Add(size)}
	draw.Draw(dst, rect, src, srcRect.Min, draw.Src)
}
Beispiel #17
0
func blur(img image.Image, howmuch float32) image.Image {
	g := gift.New(gift.Grayscale())
	g.Add(gift.GaussianBlur(howmuch))
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)
	return (dst)
}
Beispiel #18
0
func MultiScale(im image.Image, tmpls map[string]*detect.FeatTmpl, opts detect.MultiScaleOpts) ([]Det, error) {
	if len(tmpls) == 0 {
		return nil, nil
	}
	scales := imgpyr.Scales(im.Bounds().Size(), minDims(tmpls), opts.MaxScale, opts.PyrStep).Elems()
	ims := imgpyr.NewGenerator(im, scales, opts.Interp)
	pyr := featpyr.NewGenerator(ims, opts.Transform, opts.Pad)
	var dets []Det
	l, err := pyr.First()
	if err != nil {
		return nil, err
	}
	for l != nil {
		for key, tmpl := range tmpls {
			pts := detect.Points(l.Feat, tmpl.Image, tmpl.Bias, opts.DetFilter.LocalMax, opts.DetFilter.MinScore)
			// Convert to scored rectangles in the image.
			for _, pt := range pts {
				rect := pyr.ToImageRect(l.Image.Index, pt.Point, tmpl.Interior)
				dets = append(dets, Det{detect.Det{pt.Score + tmpl.Bias, rect}, key})
			}
		}
		var err error
		l, err = pyr.Next(l)
		if err != nil {
			return nil, err
		}
	}
	Sort(dets)
	inds := detect.SuppressIndex(DetSlice(dets), opts.SupprFilter.MaxNum, opts.SupprFilter.Overlap)
	dets = detsSubset(dets, inds)
	return dets, nil
}
Beispiel #19
0
func varianceF(img image.Image, disk int) (imageF, imageF) {
	m := meanF(img, disk) // gets a grayscale copy of local mean

	// create a grayscale version of the original
	//g := gift.New( gift.Grayscale() )
	//v := image.NewRGBA(g.Bounds(img.Bounds()))
	//g.Draw(v, img)

	g := gift.New(gift.Grayscale())
	dst := image.NewRGBA(g.Bounds(img.Bounds()))
	g.Draw(dst, img)

	bounds := img.Bounds()
	floatData := make([][]float32, bounds.Max.Y-bounds.Min.Y)
	for i := range floatData {
		floatData[i] = make([]float32, bounds.Max.X-bounds.Min.X)
	}
	for y := bounds.Min.X; y < bounds.Max.X; y++ {
		for x := bounds.Min.Y; x < bounds.Max.Y; x++ {
			p1r, p1g, p1b, _ := dst.At(x, y).RGBA()
			g1 := 0.2125*float64(p1r) + 0.7154*float64(p1g) + 0.0721*float64(p1b)
			g2 := float64(m[x][y])

			floatData[x][y] = float32((g1 - g2) * (g1 - g2))
		}
	}
	return m, floatData
}
Beispiel #20
0
// Canny detects and returns edges from the given image.
// Each dst pixel is given one of three values:
//   0xff: an edge
//   0x80: possibly an edge
//   0x00: not an edge
func Canny(dst *image.Gray, src image.Image) error {
	if dst == nil {
		return errors.New("edge: dst is nil")
	}
	if src == nil {
		return errors.New("edge: src is nil")
	}

	b := src.Bounds()
	srcGray, ok := src.(*image.Gray)
	if !ok {
		srcGray = image.NewGray(b)
		draw.Draw(srcGray, b, src, b.Min, draw.Src)
	}

	if err := graphics.Blur(srcGray, srcGray, nil); err != nil {
		return err
	}

	mag, dir := image.NewGray(b), image.NewGray(b)
	if err := Sobel(mag, dir, srcGray); err != nil {
		return err
	}

	// Non-maximum supression.
	for y := b.Min.Y; y < b.Max.Y; y++ {
		for x := b.Min.X; x < b.Max.X; x++ {
			d := dir.Pix[(y-b.Min.Y)*dir.Stride+(x-b.Min.X)*1]
			var m0, m1 uint8
			switch d {
			case 0: // west and east
				m0 = atOrZero(mag, x-1, y)
				m1 = atOrZero(mag, x+1, y)
			case 45: // north-east and south-west
				m0 = atOrZero(mag, x+1, y-1)
				m1 = atOrZero(mag, x-1, y+1)
			case 90: // north and south
				m0 = atOrZero(mag, x, y-1)
				m1 = atOrZero(mag, x, y+1)
			case 135: // north-west and south-east
				m0 = atOrZero(mag, x-1, y-1)
				m1 = atOrZero(mag, x+1, y+1)
			default:
				return fmt.Errorf("edge: bad direction (%d, %d): %d", x, y, d)
			}

			m := mag.Pix[(y-b.Min.Y)*mag.Stride+(x-b.Min.X)*1]
			if m > m0 && m > m1 {
				m = 0xff
			} else if m > m0 || m > m1 {
				m = 0x80
			} else {
				m = 0x00
			}
			dst.Pix[(y-b.Min.Y)*dst.Stride+(x-b.Min.X)*1] = m
		}
	}

	return nil
}
Beispiel #21
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 #22
0
// Encode image.Image with Mapniks image encoder.
func Encode(img image.Image, format string) ([]byte, error) {
	var i *C.mapnik_image_t
	switch img := img.(type) {
	// XXX does mapnik expect NRGBA or RGBA? this might stop working
	//as expected if we start encoding images with full alpha channel
	case *image.NRGBA:
		i = C.mapnik_image_from_raw(
			(*C.uint8_t)(unsafe.Pointer(&img.Pix[0])),
			C.int(img.Bounds().Dx()),
			C.int(img.Bounds().Dy()),
		)
	case *image.RGBA:
		i = C.mapnik_image_from_raw(
			(*C.uint8_t)(unsafe.Pointer(&img.Pix[0])),
			C.int(img.Bounds().Dx()),
			C.int(img.Bounds().Dy()),
		)
	}

	if i == nil {
		return nil, errors.New("unable to create image from raw")
	}
	defer C.mapnik_image_free(i)

	cformat := C.CString(format)
	b := C.mapnik_image_to_blob(i, cformat)
	if b == nil {
		return nil, errors.New("mapnik: " + C.GoString(C.mapnik_image_last_error(i)))
	}
	C.free(unsafe.Pointer(cformat))
	defer C.mapnik_image_blob_free(b)
	return C.GoBytes(unsafe.Pointer(b.ptr), C.int(b.len)), nil
}
Beispiel #23
0
func crops(i image.Image, cropWidth, cropHeight, realMinScale float64) []Crop {
	res := []Crop{}
	width := i.Bounds().Size().X
	height := i.Bounds().Size().Y

	minDimension := math.Min(float64(width), float64(height))
	var cropW, cropH float64

	if cropWidth != 0.0 {
		cropW = cropWidth
	} else {
		cropW = minDimension
	}
	if cropHeight != 0.0 {
		cropH = cropHeight
	} else {
		cropH = minDimension
	}

	for scale := maxScale; scale >= realMinScale; scale -= scaleStep {
		for y := 0; float64(y)+cropH*scale <= float64(height); y += step {
			for x := 0; float64(x)+cropW*scale <= float64(width); x += step {
				res = append(res, Crop{
					X:      x,
					Y:      y,
					Width:  int(cropW * scale),
					Height: int(cropH * scale),
				})
			}
		}
	}

	return res
}
Beispiel #24
0
// CropAnchor cuts out a rectangular region with the specified size
// from the image using the specified anchor point and returns the cropped image.
func CropAnchor(img image.Image, width, height int, anchor Anchor) *image.NRGBA {
	srcBounds := img.Bounds()
	pt := anchorPt(srcBounds, width, height, anchor)
	r := image.Rect(0, 0, width, height).Add(pt)
	b := srcBounds.Intersect(r)
	return Crop(img, b)
}
Beispiel #25
0
// create an Alpha Icon or Cursor from an Image
// http://support.microsoft.com/kb/318876
func createAlphaCursorOrIconFromImage(im image.Image, hotspot image.Point, fIcon bool) (HICON, error) {

	hBitmap, err := hBitmapFromImage(im)
	if err != nil {
		return 0, err
	}
	defer DeleteObject(HGDIOBJ(hBitmap))

	// Create an empty mask bitmap.
	hMonoBitmap := CreateBitmap(int32(im.Bounds().Dx()), int32(im.Bounds().Dy()), 1, 1, nil)
	if hMonoBitmap == 0 {
		return 0, newError("CreateBitmap failed")
	}
	defer DeleteObject(HGDIOBJ(hMonoBitmap))

	var ii ICONINFO
	if fIcon {
		ii.FIcon = TRUE
	}
	ii.XHotspot = uint32(hotspot.X)
	ii.YHotspot = uint32(hotspot.Y)
	ii.HbmMask = hMonoBitmap
	ii.HbmColor = hBitmap

	// Create the alpha cursor with the alpha DIB section.
	hIconOrCursor := CreateIconIndirect(&ii)

	return hIconOrCursor, nil
}
Beispiel #26
0
// Paste pastes the img image to the background image at the specified position and returns the combined image.
func Paste(background, img image.Image, pos image.Point) *image.NRGBA {
	src := toNRGBA(img)
	dst := Clone(background)                    // cloned image bounds start at (0, 0)
	startPt := pos.Sub(background.Bounds().Min) // so we should translate start point
	endPt := startPt.Add(src.Bounds().Size())
	pasteBounds := image.Rectangle{startPt, endPt}

	if dst.Bounds().Overlaps(pasteBounds) {
		intersectBounds := dst.Bounds().Intersect(pasteBounds)

		rowSize := intersectBounds.Dx() * 4
		numRows := intersectBounds.Dy()

		srcStartX := intersectBounds.Min.X - pasteBounds.Min.X
		srcStartY := intersectBounds.Min.Y - pasteBounds.Min.Y

		i0 := dst.PixOffset(intersectBounds.Min.X, intersectBounds.Min.Y)
		j0 := src.PixOffset(srcStartX, srcStartY)

		di := dst.Stride
		dj := src.Stride

		for row := 0; row < numRows; row++ {
			copy(dst.Pix[i0:i0+rowSize], src.Pix[j0:j0+rowSize])
			i0 += di
			j0 += dj
		}
	}

	return dst
}
Beispiel #27
0
// writeSOS writes the StartOfScan marker.
func (e *encoder) writeSOS(m image.Image) {
	e.write(sosHeader)
	var (
		// Scratch buffers to hold the YCbCr values.
		yBlock  block
		cbBlock [4]block
		crBlock [4]block
		cBlock  block
		// DC components are delta-encoded.
		prevDCY, prevDCCb, prevDCCr int
	)
	bounds := m.Bounds()
	rgba, _ := m.(*image.RGBA)
	for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 {
		for x := bounds.Min.X; x < bounds.Max.X; x += 16 {
			for i := 0; i < 4; i++ {
				xOff := (i & 1) * 8
				yOff := (i & 2) * 4
				p := image.Point{x + xOff, y + yOff}
				if rgba != nil {
					rgbaToYCbCr(rgba, p, &yBlock, &cbBlock[i], &crBlock[i])
				} else {
					toYCbCr(m, p, &yBlock, &cbBlock[i], &crBlock[i])
				}
				prevDCY = e.writeBlock(&yBlock, 0, prevDCY)
			}
			scale(&cBlock, &cbBlock)
			prevDCCb = e.writeBlock(&cBlock, 1, prevDCCb)
			scale(&cBlock, &crBlock)
			prevDCCr = e.writeBlock(&cBlock, 1, prevDCCr)
		}
	}
	// Pad the last byte with 1's.
	e.emit(0x7f, 7)
}
/**
 * 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
}
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
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
}