Beispiel #1
0
// initLayout constructs two masks for drawing the battery and the remaining
// energy as well as sets the pixel bounds for drawing energy capacity.  the
// masks allow for simplified space-fills and reduced chance of pixel gaps.
func (app *App) initLayout() {
	var zeropt image.Point

	rectOutTop := image.Rectangle{Min: app.Layout.battRect.Min, Max: app.Layout.battRect.Min.Add(image.Point{2, 2})}
	rectOutBottom := rectOutTop.Add(image.Point{Y: app.Layout.battRect.Size().Y - rectOutTop.Size().Y})
	capRect := image.Rectangle{
		Min: image.Point{X: rectOutTop.Min.X, Y: rectOutTop.Max.Y},
		Max: image.Point{X: rectOutBottom.Max.X, Y: rectOutBottom.Min.Y},
	}
	bodyRect := app.Layout.battRect
	bodyRect.Min.X = capRect.Max.X

	// energy will be drawn under the battery shell.  The only place where it
	// is not safe to draw energy is outside the battery on the positive end.
	energyMask := image.NewAlpha(app.Layout.battRect)
	draw.Draw(energyMask, app.Layout.battRect, opaque, zeropt, draw.Over)
	draw.Draw(energyMask, rectOutTop, transparent, zeropt, draw.Src)
	draw.Draw(energyMask, rectOutBottom, transparent, zeropt, draw.Src)
	app.maskEnergy = energyMask

	// the body uses the same mask as the energy with additional transparency
	// inside the battery's shell.  the mask construction is complex because
	// area inside the cap may be exposed.
	bodyMask := image.NewAlpha(app.Layout.battRect)
	draw.Draw(bodyMask, app.Layout.battRect, energyMask, app.Layout.battRect.Min, draw.Over)
	bodyMaskRect := shrinkRect(bodyRect, app.Layout.thickness)
	draw.Draw(bodyMask, bodyMaskRect, transparent, zeropt, draw.Src)
	capMaskRect := shrinkRect(capRect, app.Layout.thickness)
	capMaskRect.Max.X += 2 * app.Layout.thickness
	draw.Draw(bodyMask, capMaskRect, transparent, zeropt, draw.Src)
	app.maskBattery = bodyMask

	// create a freetype.Context to render text.  each time the context is used
	// it must have its SetDst method called.
	app.tt = freetype.NewContext()
	app.tt.SetSrc(black)
	app.tt.SetClip(app.Layout.textRect)
	app.tt.SetDPI(app.Layout.DPI)
	app.tt.SetFont(app.Layout.font)
	app.tt.SetFontSize(app.Layout.fontSize)
	ttopt := &truetype.Options{
		Size: app.Layout.fontSize,
		DPI:  app.Layout.DPI,
	}
	ttface := truetype.NewFace(app.Layout.font, ttopt)
	app.font = &font.Drawer{
		Src:  black,
		Face: ttface,
	}

	// the rectangle in which energy is drawn needs to account for thickness to
	// make the visible percentage more accurate.  after adjustment reduce the
	// energy rect to account for the account of energy drained.  the energy
	// mask makes computing Y bounds largely irrelevant.
	app.minEnergy = capMaskRect.Min.X
	app.maxEnergy = bodyMaskRect.Max.X
}
Beispiel #2
0
// NewDrawableSize returns a new draw.Image with the same type as p and the given bounds.
// If p is not a draw.Image, another type is used.
func NewDrawableSize(p image.Image, r image.Rectangle) draw.Image {
	switch p := p.(type) {
	case *image.RGBA:
		return image.NewRGBA(r)
	case *image.RGBA64:
		return image.NewRGBA64(r)
	case *image.NRGBA:
		return image.NewNRGBA(r)
	case *image.NRGBA64:
		return image.NewNRGBA64(r)
	case *image.Alpha:
		return image.NewAlpha(r)
	case *image.Alpha16:
		return image.NewAlpha16(r)
	case *image.Gray:
		return image.NewGray(r)
	case *image.Gray16:
		return image.NewGray16(r)
	case *image.Paletted:
		pl := make(color.Palette, len(p.Palette))
		copy(pl, p.Palette)
		return image.NewPaletted(r, pl)
	case *image.CMYK:
		return image.NewCMYK(r)
	default:
		return image.NewRGBA(r)
	}
}
Beispiel #3
0
// rasterize returns the advance width, glyph mask and integer-pixel offset
// to render the given glyph at the given sub-pixel offsets.
// The 24.8 fixed point arguments fx and fy must be in the range [0, 1).
func (c *Context) rasterize(glyph truetype.Index, fx, fy raster.Fix32) (
	raster.Fix32, *image.Alpha, image.Point, error) {

	if err := c.glyphBuf.Load(c.font, c.scale, glyph, truetype.Hinting(c.hinting)); err != nil {
		return 0, nil, image.Point{}, err
	}
	// Calculate the integer-pixel bounds for the glyph.
	xmin := int(fx+raster.Fix32(c.glyphBuf.B.XMin<<2)) >> 8
	ymin := int(fy-raster.Fix32(c.glyphBuf.B.YMax<<2)) >> 8
	xmax := int(fx+raster.Fix32(c.glyphBuf.B.XMax<<2)+0xff) >> 8
	ymax := int(fy-raster.Fix32(c.glyphBuf.B.YMin<<2)+0xff) >> 8
	if xmin > xmax || ymin > ymax {
		return 0, nil, image.Point{}, errors.New("freetype: negative sized glyph")
	}
	// A TrueType's glyph's nodes can have negative co-ordinates, but the
	// rasterizer clips anything left of x=0 or above y=0. xmin and ymin
	// are the pixel offsets, based on the font's FUnit metrics, that let
	// a negative co-ordinate in TrueType space be non-negative in
	// rasterizer space. xmin and ymin are typically <= 0.
	fx += raster.Fix32(-xmin << 8)
	fy += raster.Fix32(-ymin << 8)
	// Rasterize the glyph's vectors.
	c.r.Clear()
	e0 := 0
	for _, e1 := range c.glyphBuf.End {
		c.drawContour(c.glyphBuf.Point[e0:e1], fx, fy)
		e0 = e1
	}
	a := image.NewAlpha(image.Rect(0, 0, xmax-xmin, ymax-ymin))
	c.r.Rasterize(raster.NewAlphaSrcPainter(a))
	return raster.Fix32(c.glyphBuf.AdvanceWidth << 2), a, image.Point{xmin, ymin}, nil
}
Beispiel #4
0
// textBox renders t into a tight fitting image
func (ig *ImageGraphics) textBox(t string, size int) image.Image {
	// Initialize the context.
	fg := image.NewUniform(color.Alpha{0xff})
	bg := image.NewUniform(color.Alpha{0x00})
	canvas := image.NewAlpha(image.Rect(0, 0, 400, 2*size))
	draw.Draw(canvas, canvas.Bounds(), bg, image.ZP, draw.Src)

	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(ig.font)
	c.SetFontSize(float64(size))
	c.SetClip(canvas.Bounds())
	c.SetDst(canvas)
	c.SetSrc(fg)

	// Draw the text.
	h := c.FUnitToPixelRU(ig.font.UnitsPerEm())
	pt := freetype.Pt(0, h)
	extent, err := c.DrawString(t, pt)
	if err != nil {
		log.Println(err)
		return nil
	}
	// log.Printf("text %q, extent: %v", t, extent)
	return canvas.SubImage(image.Rect(0, 0, int(extent.X/256), h*5/4))
}
Beispiel #5
0
func main() {
	var err error
	gophersImage, _, err = common.AssetImage("gophers.jpg", ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	fiveyearsImage, _, err = common.AssetImage("fiveyears.jpg", ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	maskImage, err = ebiten.NewImage(screenWidth, screenHeight, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}

	as := image.Point{128, 128}
	a := image.NewAlpha(image.Rectangle{image.ZP, as})
	for j := 0; j < as.Y; j++ {
		for i := 0; i < as.X; i++ {
			r := as.X / 2
			d := math.Sqrt(float64((i-r)*(i-r) + (j-r)*(j-r)))
			b := uint8(max(0, min(0xff, 3*0xff-int(d*3*0xff)/r)))
			a.SetAlpha(i, j, color.Alpha{b})
		}
	}
	spotLightImage, err = ebiten.NewImageFromImage(a, ebiten.FilterNearest)
	if err != nil {
		log.Fatal(err)
	}
	if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Masking (Ebiten Demo)"); err != nil {
		log.Fatal(err)
	}
}
Beispiel #6
0
// Save saves the texture as a PNG image.
func (a *TextureAtlas) Save(file string) (err error) {
	fd, err := os.Create(file)
	if err != nil {
		return
	}

	defer fd.Close()

	rect := image.Rect(0, 0, a.width, a.height)

	switch a.depth {
	case 1:
		img := image.NewAlpha(rect)
		copy(img.Pix, a.data)
		err = png.Encode(fd, img)

	case 3:
		img := image.NewRGBA(rect)
		copy(img.Pix, a.data)
		err = png.Encode(fd, img)

	case 4:
		img := image.NewRGBA(rect)
		copy(img.Pix, a.data)
		err = png.Encode(fd, img)
	}

	return
}
Beispiel #7
0
func NewImageOfTypeRect(src image.Image, bounds image.Rectangle) image.Image {
	switch i := src.(type) {
	case *image.Alpha:
		return image.NewAlpha(bounds)
	case *image.Alpha16:
		return image.NewAlpha16(bounds)
	case *image.Gray:
		return image.NewGray(bounds)
	case *image.Gray16:
		return image.NewGray16(bounds)
	case *image.NRGBA:
		return image.NewNRGBA(bounds)
	case *image.NRGBA64:
		return image.NewNRGBA64(bounds)
	case *image.Paletted:
		return image.NewPaletted(bounds, i.Palette)
	case *image.RGBA:
		return image.NewRGBA(bounds)
	case *image.RGBA64:
		return image.NewRGBA64(bounds)
	case *image.YCbCr:
		return image.NewYCbCr(bounds, i.SubsampleRatio)
	}
	panic("Unknown image type")
}
Beispiel #8
0
func (c *Context) rasterize(glyph uint16, fx, fy Fix32) (*image.Alpha, image.Point, error) {
	if err := c.glyph.Load(c.font, c.scale, glyph, nil); err != nil {
		return nil, image.ZP, err
	}

	xmin := int(fx+Fix32(c.glyph.Rect.XMin<<2)) >> 8
	ymin := int(fy-Fix32(c.glyph.Rect.YMax<<2)) >> 8
	xmax := int(fx+Fix32(c.glyph.Rect.XMax<<2)+0xff) >> 8
	ymax := int(fy-Fix32(c.glyph.Rect.YMin<<2)+0xff) >> 8
	if xmin > xmax || ymin > ymax {
		return nil, image.ZP, errors.New("freetype negative sized glyph")
	}

	fx += Fix32(-xmin << 8)
	fy += Fix32(-ymin << 8)

	c.rast.Clear()

	e0 := 0

	for _, e1 := range c.glyph.EndIndexArray {
		c.drawContour(c.glyph.AllPoints[e0:e1], fx, fy)
		e0 = e1
	}

	a := image.NewAlpha(image.Rect(0, 0, xmax-xmin, ymax-ymin))
	c.rast.Rast(NewAlphaSrcDrawer(a))

	return a, image.Point{xmin, ymin}, nil
}
Beispiel #9
0
// rasterize returns the advance width, glyph mask and integer-pixel offset
// to render the given glyph at the given sub-pixel offsets.
// The 26.6 fixed point arguments fx and fy must be in the range [0, 1).
func (c *Context) rasterize(glyph truetype.Index, fx, fy fixed.Int26_6) (
	fixed.Int26_6, *image.Alpha, image.Point, error) {

	if err := c.glyphBuf.Load(c.f, c.scale, glyph, c.hinting); err != nil {
		return 0, nil, image.Point{}, err
	}
	// Calculate the integer-pixel bounds for the glyph.
	xmin := int(fx+c.glyphBuf.Bounds.Min.X) >> 6
	ymin := int(fy-c.glyphBuf.Bounds.Max.Y) >> 6
	xmax := int(fx+c.glyphBuf.Bounds.Max.X+0x3f) >> 6
	ymax := int(fy-c.glyphBuf.Bounds.Min.Y+0x3f) >> 6
	if xmin > xmax || ymin > ymax {
		return 0, nil, image.Point{}, errors.New("freetype: negative sized glyph")
	}
	// A TrueType's glyph's nodes can have negative co-ordinates, but the
	// rasterizer clips anything left of x=0 or above y=0. xmin and ymin are
	// the pixel offsets, based on the font's FUnit metrics, that let a
	// negative co-ordinate in TrueType space be non-negative in rasterizer
	// space. xmin and ymin are typically <= 0.
	fx -= fixed.Int26_6(xmin << 6)
	fy -= fixed.Int26_6(ymin << 6)
	// Rasterize the glyph's vectors.
	c.r.Clear()
	e0 := 0
	for _, e1 := range c.glyphBuf.Ends {
		c.drawContour(c.glyphBuf.Points[e0:e1], fx, fy)
		e0 = e1
	}
	a := image.NewAlpha(image.Rect(0, 0, xmax-xmin, ymax-ymin))
	c.r.Rasterize(raster.NewAlphaSrcPainter(a))
	return c.glyphBuf.AdvanceWidth, a, image.Point{xmin, ymin}, nil
}
Beispiel #10
0
// NewFace returns a new font.Face for the given Font.
func NewFace(f *Font, opts *Options) font.Face {
	a := &face{
		f:          f,
		hinting:    opts.hinting(),
		scale:      fixed.Int26_6(0.5 + (opts.size() * opts.dpi() * 64 / 72)),
		glyphCache: make([]glyphCacheEntry, opts.glyphCacheEntries()),
	}
	a.subPixelX, a.subPixelBiasX, a.subPixelMaskX = opts.subPixelsX()
	a.subPixelY, a.subPixelBiasY, a.subPixelMaskY = opts.subPixelsY()

	// Fill the cache with invalid entries. Valid glyph cache entries have fx
	// and fy in the range [0, 64). Valid index cache entries have rune >= 0.
	for i := range a.glyphCache {
		a.glyphCache[i].key.fy = 0xff
	}
	for i := range a.indexCache {
		a.indexCache[i].rune = -1
	}

	// Set the rasterizer's bounds to be big enough to handle the largest glyph.
	b := f.Bounds(a.scale)
	xmin := +int(b.Min.X) >> 6
	ymin := -int(b.Max.Y) >> 6
	xmax := +int(b.Max.X+63) >> 6
	ymax := -int(b.Min.Y-63) >> 6
	a.maxw = xmax - xmin
	a.maxh = ymax - ymin
	a.masks = image.NewAlpha(image.Rect(0, 0, a.maxw, a.maxh*len(a.glyphCache)))
	a.r.SetBounds(a.maxw, a.maxh)
	a.p = facePainter{a}

	return a
}
Beispiel #11
0
// textBox renders t into a tight fitting image
func (ig *ImageGraphics) textBox(t string, font chart.Font) image.Image {
	// Initialize the context.
	fg := image.NewUniform(color.Alpha{0xff})
	bg := image.NewUniform(color.Alpha{0x00})
	width := ig.TextLen(t, font)
	size := ig.relFontsizeToPixel(font.Size)
	canvas := image.NewAlpha(image.Rect(0, 0, width, int(1.5*size+0.5)))
	draw.Draw(canvas, canvas.Bounds(), bg, image.ZP, draw.Src)

	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(ig.font)
	c.SetFontSize(size)
	c.SetClip(canvas.Bounds())
	c.SetDst(canvas)
	c.SetSrc(fg)

	// Draw the text.
	h := c.FUnitToPixelRU(ig.font.UnitsPerEm())
	pt := freetype.Pt(0, h)
	extent, err := c.DrawString(t, pt)
	if err != nil {
		log.Println(err)
		return nil
	}
	// log.Printf("text %q, extent: %v", t, extent)
	return canvas.SubImage(image.Rect(0, 0, int((extent.X+127)/256), h*5/4))
}
Beispiel #12
0
func createRandomImage(maxPaletteSize int) image.Image {
	r := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{gen.Rand(32) + 1, gen.Rand(32) + 1}}
	var img Image
	switch gen.Rand(10) {
	case 0:
		img = image.NewAlpha(r)
	case 1:
		img = image.NewAlpha16(r)
	case 2:
		img = image.NewCMYK(r)
	case 3:
		img = image.NewGray(r)
	case 4:
		img = image.NewGray16(r)
	case 5:
		img = image.NewNRGBA(r)
	case 6:
		img = image.NewNRGBA64(r)
	case 7:
		img = image.NewPaletted(r, randPalette(maxPaletteSize))
	case 8:
		img = image.NewRGBA(r)
	case 9:
		img = image.NewRGBA64(r)
	default:
		panic("bad")
	}
	fill := gen.Rand(19)
	var palette []color.Color
	if fill == 17 {
		palette = randPalette(maxPaletteSize)
	}
	for y := 0; y < r.Max.Y; y++ {
		for x := 0; x < r.Max.X; x++ {
			switch {
			case fill <= 15:
				img.Set(x, y, color.RGBA64{
					^uint16(0) * uint16((fill>>0)&1),
					^uint16(0) * uint16((fill>>1)&1),
					^uint16(0) * uint16((fill>>2)&1),
					^uint16(0) * uint16((fill>>3)&1),
				})
			case fill == 16:
				img.Set(x, y, randColor())
			case fill == 17:
				img.Set(x, y, palette[gen.Rand(len(palette))])
			case fill == 18:
				if gen.Rand(3) != 0 {
					img.Set(x, y, color.RGBA64{})
				} else {
					img.Set(x, y, randColor())
				}
			default:
				panic("bad")
			}
		}
	}
	return img.(image.Image)
}
Beispiel #13
0
func (d Draw) save() {
	r := raster.NewRasterizer()
	mask := image.NewAlpha(image.Rect(0, 0, d.Width, d.Height))
	img := image.NewRGBA(image.Rect(0, 0, d.Width, d.Height))
	r.Fill(mask, d.Polygons[0], false)
	raster.DrawSolidRGBA(img, mask, color.RGBAModel.Convert(d.Color).(color.RGBA))
	savepng("_test"+d.Name+".png", img)
}
Beispiel #14
0
// ConvertToAlpha returns an *image.Alpha instance by asserting the given
// ImageReader has that type or, if it does not, using Copy to concurrently
// set the color.Color values of a new *image.Alpha instance with the same
// bounds.
func ConvertToAlpha(src ImageReader) *image.Alpha {
	if dst, ok := src.(*image.Alpha); ok {
		return dst
	}
	dst := image.NewAlpha(src.Bounds())
	Copy(dst, src)
	return dst
}
Beispiel #15
0
func main() {
	fd, _ := os.OpenFile("log.txt", os.O_RDWR|os.O_CREATE, 0666)
	defer fd.Close()

	log.SetOutput(fd)

	// Draw a rounded corner that is one pixel wide.
	r := ft.NewRast(50, 50)
	r.Start(p(5, 5))
	r.Add1(p(5, 25))
	r.Add2(p(5, 45), p(25, 45))
	r.Add1(p(45, 45))
	r.Add1(p(45, 44))
	r.Add1(p(26, 44))
	r.Add2(p(6, 44), p(6, 24))
	r.Add1(p(6, 5))
	r.Add1(p(5, 5))

	// Rasterize that curve multiple times at different gammas.
	const (
		w = 600
		h = 200
	)
	rgba := image.NewRGBA(image.Rect(0, 0, w, h))
	draw.Draw(rgba, image.Rect(0, 0, w, h/2), image.Black, image.ZP, draw.Src)
	draw.Draw(rgba, image.Rect(0, h/2, w, h), image.White, image.ZP, draw.Src)
	mask := image.NewAlpha(image.Rect(0, 0, 50, 50))
	drawer := ft.NewAlphaSrcDrawer(mask)
	gammas := []float64{1.0 / 10.0, 1.0 / 3.0, 1.0 / 2.0, 2.0 / 3.0, 4.0 / 5.0, 1.0, 5.0 / 4.0, 3.0 / 2.0, 2.0, 3.0, 10.0}
	for i, g := range gammas {
		draw.Draw(mask, mask.Bounds(), image.Transparent, image.ZP, draw.Src)
		r.Rast(ft.NewGammaCorrectionDrawer(drawer, g))
		x, y := 50*i+25, 25
		draw.DrawMask(rgba, image.Rect(x, y, x+50, y+50), image.White, image.ZP, mask, image.ZP, draw.Over)
		y += 100
		draw.DrawMask(rgba, image.Rect(x, y, x+50, y+50), image.Black, image.ZP, mask, image.ZP, draw.Over)
	}

	// Save that RGBA image to disk.
	f, err := os.Create("out.png")
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	defer f.Close()
	b := bufio.NewWriter(f)
	err = png.Encode(b, rgba)
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	err = b.Flush()
	if err != nil {
		log.Println(err)
		os.Exit(1)
	}
	fmt.Println("Wrote out.png OK.")
}
Beispiel #16
0
func vgradAlpha(alpha int) image.Image {
	m := image.NewAlpha(16, 16)
	for y := 0; y < 16; y++ {
		for x := 0; x < 16; x++ {
			m.Set(x, y, image.AlphaColor{uint8(y * alpha / 15)})
		}
	}
	return m
}
Beispiel #17
0
func vgradAlpha(alpha int) image.Image {
	m := image.NewAlpha(image.Rect(0, 0, 16, 16))
	for y := 0; y < 16; y++ {
		for x := 0; x < 16; x++ {
			m.Set(x, y, color.Alpha{uint8(y * alpha / 15)})
		}
	}
	return m
}
Beispiel #18
0
func (self *face) Glyph(dot fixed.Point26_6, char rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
	var bounds fixed.Rectangle26_6
	var cached bool
	var cachedGlyph glyph

	if cachedGlyph, cached = self.cache.get(char); cached {
		bounds, advance, mask = cachedGlyph.bounds, cachedGlyph.advance, cachedGlyph.mask
	}

	if bounds == (fixed.Rectangle26_6{}) || advance == 0 {
		if bounds, advance, ok = self.GlyphBounds(char); !ok {
			return
		}
	}

	offset := fixed.Point26_6{
		X: abs26_6(bounds.Min.X),
		Y: self.metrics.Ascent,
	}

	origin := C.CGPoint{
		x: C.CGFloat(f64(offset.X)),
		y: C.CGFloat(f64(offset.Y)),
	}

	dx := (int(bounds.Max.X+offset.X) >> 6) + 1
	dy := (int(self.metrics.Ascent+self.metrics.Descent) >> 6) + 1

	dr.Min.X = (int(dot.X) >> 6) - int(origin.x)
	dr.Min.Y = (int(dot.Y) >> 6) - int(origin.y)
	dr.Max.X = dr.Min.X + dx
	dr.Max.Y = dr.Min.Y + dy

	if mask == nil {
		alpha := image.NewAlpha(image.Rect(0, 0, dx, dy))

		if !C.CTFontGlyphDraw__(
			self.ref,
			C.UTF32Char(char),
			origin,
			(*C.UInt8)(unsafe.Pointer(&alpha.Pix[0])),
			C.size_t(alpha.Stride),
			C.size_t(dx),
			C.size_t(dy),
		) {
			dr, advance = image.Rectangle{}, 0
			return
		}

		mask = alpha
		self.cache.set(glyph{rune: char, bounds: bounds, advance: advance, mask: mask})
	}

	ok = true
	return
}
Beispiel #19
0
// MaskForCharacter returns an 4x6 black-and-white image mask for
// the given character. Useful for image/draw.DrawMask().
func MaskForCharacter(c byte) image.Image {
	mask := image.NewAlpha(image.Rect(0, 0, 4, 6))
	rows := font[int(c)]
	for y, row := range rows {
		for x := uint(0); x < 4; x++ {
			if (row>>x)&1 > 0 {
				mask.Set(4-(int(x)+1), y, color.Black)
			}
		}
	}
	return mask
}
Beispiel #20
0
func avatarImageProvider(id string, width, height int) image.Image {
	var r io.Reader

	if c := getContactForTel(id); c != nil {
		r = strings.NewReader(c.Photo)
	}

	if g, ok := groups[id]; ok {
		r = bytes.NewReader(g.Avatar)
	}

	if r == nil {
		return image.NewAlpha(image.Rectangle{})
	}
	img, _, err := image.Decode(r)
	if err != nil {
		return image.NewAlpha(image.Rectangle{})

	}
	return img
}
Beispiel #21
0
func (d *decoder) decode(r io.Reader) (err error) {
	if err = d.decodeHeader(r); err != nil {
		return err
	}
	if err = d.decodeEntries(r); err != nil {
		return err
	}
	d.images = make([]image.Image, d.head.Number)
	for i, _ := range d.entries {
		e := &(d.entries[i])
		data := make([]byte, e.Size+14)
		n, err := io.ReadFull(r, data[14:])
		if err != nil && err != io.ErrUnexpectedEOF {
			return err
		}
		data = data[:14+n]
		if n > 8 && bytes.Compare(data[14:22], pngHeader) == 0 { // decode as PNG
			if d.images[i], err = png.Decode(bytes.NewReader(data[14:])); err != nil {
				return err
			}
		} else { // decode as BMP
			maskData := d.forgeBMPHead(data, e)
			if maskData != nil {
				data = data[:n+14-len(maskData)]
			}
			if d.images[i], err = bmp.Decode(bytes.NewReader(data)); err != nil {
				return err
			}
			bounds := d.images[i].Bounds()
			mask := image.NewAlpha(image.Rect(0, 0, bounds.Dx(), bounds.Dy()))
			masked := image.NewNRGBA(image.Rect(0, 0, bounds.Dx(), bounds.Dy()))
			for row := 0; row < int(e.Height); row++ {
				for col := 0; col < int(e.Width); col++ {
					if maskData != nil {
						rowSize := (int(e.Width) + 31) / 32 * 4
						if (maskData[row*rowSize+col/8]>>(7-uint(col)%8))&0x01 != 1 {
							mask.SetAlpha(col, int(e.Height)-row-1, color.Alpha{255})
						}
					} else { // 32-Bit
						rowSize := (int(e.Width)*32 + 31) / 32 * 4
						offset := int(binary.LittleEndian.Uint32(data[10:14]))
						mask.SetAlpha(col, int(e.Height)-row-1, color.Alpha{data[offset+row*rowSize+col*4+3]})
					}
				}
			}
			draw.DrawMask(masked, masked.Bounds(), d.images[i], bounds.Min, mask, bounds.Min, draw.Src)
			d.images[i] = masked
		}
	}
	return nil
}
Beispiel #22
0
// Decode decodes an image from the given data.
func Decode(r io.Reader) (img image.Image, err error) {
	defer func() {
		if x := recover(); x != nil {
			err = fmt.Errorf("Decode: %v", x)
		}
	}()

	br := bufio.NewReader(r)
	format := readS(br)
	width := readU(br)
	height := readU(br)
	rect := image.Rect(0, 0, int(width), int(height))

	switch format {
	case "P1":
		img = image.NewAlpha(rect)
		decodeP1(br, img.(draw.Image), width, height)
	case "P2":
		img = image.NewGray(rect)
		decodeP2(br, img.(draw.Image), width, height)
	case "P3":
		img = image.NewRGBA(rect)
		decodeP3(br, img.(draw.Image), width, height)
	case "P4":
		img = image.NewAlpha(rect)
		decodeP4(br, img.(draw.Image), width, height)
	case "P5":
		img = image.NewGray(rect)
		decodeP5(br, img.(draw.Image), width, height)
	case "P6":
		img = image.NewRGBA(rect)
		decodeP6(br, img.(draw.Image), width, height)
	default:
		panic("Unknown PPM format: " + format)
	}

	return
}
func TestQuadCurve(t *testing.T) {
	for i, curve := range testsQuadFloat64 {
		var p Path
		p.LineTo(curve[0], curve[1])
		curve.Segment(&p, flattening_threshold)
		img := image.NewAlpha(image.Rect(0, 0, 300, 300))
		raster.DrawPolyline(img, curve[:]...)
		raster.DrawPolyline(img, p.points...)
		drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
		savepng(fmt.Sprintf("_testQuad%d.png", i), img)
		log.Printf("Num of points: %d\n", len(p.points))
	}
	fmt.Println()
}
Beispiel #24
0
func TestRasterize30Degrees(t *testing.T) {
	z := NewRasterizer(8, 8)
	z.MoveTo(4, 4)
	z.LineTo(8, 4)
	z.LineTo(4, 6)
	z.ClosePath()

	dst := image.NewAlpha(z.Bounds())
	z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})

	if err := checkCornersCenter(dst); err != nil {
		t.Error(err)
	}
}
func TestCubicCurveAdaptive(t *testing.T) {
	for i, curve := range testsCubicFloat64 {
		var p Path
		p.LineTo(curve[0], curve[1])
		curve.AdaptiveSegment(&p, 1, 0, 0)
		img := image.NewAlpha(image.Rect(0, 0, 300, 300))
		raster.DrawPolyline(img, curve[:]...)
		raster.DrawPolyline(img, p.points...)
		drawPoints(img, color.NRGBA{0, 0, 0, 0xff}, p.points...)
		savepng(fmt.Sprintf("_testAdaptive%d.png", i), img)
		log.Printf("Num of points: %d\n", len(p.points))
	}
	fmt.Println()
}
Beispiel #26
0
func TestNewPixelGetter(t *testing.T) {
	var img image.Image
	var pg *pixelGetter
	img = image.NewNRGBA(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itNRGBA || pg.imgNRGBA == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter NRGBA")
	}
	img = image.NewNRGBA64(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itNRGBA64 || pg.imgNRGBA64 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter NRGBA64")
	}
	img = image.NewRGBA(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itRGBA || pg.imgRGBA == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter RGBA")
	}
	img = image.NewRGBA64(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itRGBA64 || pg.imgRGBA64 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter RGBA64")
	}
	img = image.NewGray(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGray || pg.imgGray == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Gray")
	}
	img = image.NewGray16(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGray16 || pg.imgGray16 == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Gray16")
	}
	img = image.NewYCbCr(image.Rect(0, 0, 1, 1), image.YCbCrSubsampleRatio422)
	pg = newPixelGetter(img)
	if pg.imgType != itYCbCr || pg.imgYCbCr == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter YCbCr")
	}
	img = image.NewUniform(color.NRGBA64{0, 0, 0, 0})
	pg = newPixelGetter(img)
	if pg.imgType != itGeneric || pg.imgGeneric == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Generic(Uniform)")
	}
	img = image.NewAlpha(image.Rect(0, 0, 1, 1))
	pg = newPixelGetter(img)
	if pg.imgType != itGeneric || pg.imgGeneric == nil || !img.Bounds().Eq(pg.imgBounds) {
		t.Error("newPixelGetter Generic(Alpha)")
	}
}
func TestSimpleRasterizer(t *testing.T) {
	bounds := image.Rect(0, 0, 200, 200)
	img := image.NewRGBA(bounds)
	mask := image.NewAlpha(bounds)
	var p Path
	p.LineTo(10, 190)
	c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
	c.Segment(&p, flattening_threshold)
	poly := Polygon(p.points)
	rgba := color.RGBA{0, 0, 0, 0xff}
	r := NewRasterizer()
	r.Fill(mask, poly, false)
	DrawSolidRGBA(img, mask, rgba)
	savepng("_testSimpleRasterizer.png", img)
}
Beispiel #28
0
func TestRasterizeAlmostAxisAligned(t *testing.T) {
	z := NewRasterizer(8, 8)
	z.MoveTo(2, 2)
	z.LineTo(6, math.Nextafter32(2, 0))
	z.LineTo(6, 6)
	z.LineTo(math.Nextafter32(2, 0), 6)
	z.ClosePath()

	dst := image.NewAlpha(z.Bounds())
	z.Draw(dst, dst.Bounds(), image.Opaque, image.Point{})

	if err := checkCornersCenter(dst); err != nil {
		t.Error(err)
	}
}
Beispiel #29
0
func BenchmarkRasterizerNonZeroWinding(b *testing.B) {
	var p Path
	p.LineTo(10, 190)
	draw2dbase.TraceCubic(&p, []float64{10, 190, 10, 10, 190, 10, 190, 190}, 0.5)
	poly := Polygon(p.points)
	rgba := color.RGBA{0, 0, 0, 0xff}
	rasterizer := NewRasterizer()
	for i := 0; i < b.N; i++ {
		bounds := image.Rect(0, 0, 200, 200)
		img := image.NewRGBA(bounds)
		mask := image.NewAlpha(bounds)
		rasterizer.Fill(mask, poly, true)
		DrawSolidRGBA(img, mask, rgba)
	}
}
func BenchmarkSimpleRasterizerNonZero(b *testing.B) {
	var p Path
	p.LineTo(10, 190)
	c := curve.CubicCurveFloat64{10, 190, 10, 10, 190, 10, 190, 190}
	c.Segment(&p, flattening_threshold)
	poly := Polygon(p.points)
	rgba := color.RGBA{0, 0, 0, 0xff}
	rasterizer := NewRasterizer()
	for i := 0; i < b.N; i++ {
		bounds := image.Rect(0, 0, 200, 200)
		img := image.NewRGBA(bounds)
		mask := image.NewAlpha(bounds)
		rasterizer.Fill(mask, poly, true)
		DrawSolidRGBA(img, mask, rgba)
	}
}