Пример #1
1
func drawText(font *truetype.Font, c *freetype.Context, color color.Color, rgba *image.RGBA, text string) (int, int) {
	fg := image.NewUniform(color)
	bg := image.Transparent
	draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
	c.SetFont(font)
	c.SetDst(rgba)
	c.SetSrc(fg)
	c.SetClip(rgba.Bounds())
	// height is the fraction of the font that is above the line, 1.0 would mean
	// that the font never falls below the line
	// TODO: wtf - this is all wrong!
	// fix fonts - we can't change the font size easily
	height := 1.3
	pt := freetype.Pt(0, int(float64(c.PointToFixed(*size)>>8)*height))
	adv, _ := c.DrawString(text, pt)
	pt.X += adv.X
	py := int(float64(pt.Y>>8)/height + 0.01)
	return int(pt.X >> 8), py
}
Пример #2
0
// CenterX returns the Point at which string s will be centered within rect r
// along the X coordinate when passed to c.DrawString. The Y coordinate will be 0.
// Clip is set to r before returning.
func CenterX(c *freetype.Context, s string, r image.Rectangle) (fixed.Point26_6, error) {
	w, err := DrawWidth(c, s)
	c.SetClip(r)
	if err != nil {
		return fixed.Point26_6{}, err
	}
	half := Int26_6(0.5)
	xmin := freetype.Pt(r.Min.X, 0)
	return freetype.Pt(r.Dx(), 0).Mul(half).Sub(w.Mul(half)).Add(xmin), nil
}
Пример #3
0
func (f *Font) Render(text string) *Texture {
	width, height, yBearing := f.TextDimensions(text)
	font := f.ttf
	size := f.Size

	// Colors
	fg := image.NewUniform(color.NRGBA{f.FG.R, f.FG.G, f.FG.B, f.FG.A})
	bg := image.NewUniform(color.NRGBA{f.BG.R, f.BG.G, f.BG.B, f.BG.A})

	// Create the font context
	c := freetype.NewContext()

	nrgba := image.NewNRGBA(image.Rect(0, 0, width, height))
	draw.Draw(nrgba, nrgba.Bounds(), bg, image.ZP, draw.Src)

	c.SetDPI(dpi)
	c.SetFont(font)
	c.SetFontSize(size)
	c.SetClip(nrgba.Bounds())
	c.SetDst(nrgba)
	c.SetSrc(fg)

	// Draw the text.
	pt := freetype.Pt(0, int(yBearing))
	_, err := c.DrawString(text, pt)
	if err != nil {
		log.Println(err)
		return nil
	}

	// Create texture
	imObj := &ImageObject{nrgba}
	return NewTexture(imObj)

}
Пример #4
0
func (this *Signer) drawStringImage(text string) (image.Image, error) {
	fontBytes, err := ioutil.ReadFile(this.fontPath)
	if err != nil {
		fmt.Println(err)
	}

	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		fmt.Println(err)
	}

	rgba := image.NewRGBA(image.Rect(0, 0, 900, 900))

	draw.Draw(rgba, rgba.Bounds(), image.Black, image.ZP, draw.Src)
	c := freetype.NewContext()
	c.SetDPI(this.dpi)
	c.SetFontSize(this.fontSize)
	c.SetClip(rgba.Bounds())
	c.SetDst(rgba)
	c.SetSrc(image.White)
	c.SetFont(font)

	pt := freetype.Pt(100, 100+int(c.PointToFixed(this.fontSize)>>8))
	for _, s := range strings.Split(text, "\r\n") {
		_, err = c.DrawString(s, pt)
		pt.Y += c.PointToFixed(12 * 1.5)

	}

	return rgba, nil

}
Пример #5
0
func drawBarcode(img *image.Gray, unitSize, xPos, yPos float64, num int) {
	drawSO(img, unitSize, xPos, yPos)
	x := xPos + unitSize*4.0

	// Draw reference bar
	x += drawBar(img, unitSize, x, yPos, 0) + unitSize

	// Print the form number below the barcode
	ftContext.SetFontSize(7)
	ftContext.SetSrc(image.NewUniform(color.Black))
	ftContext.DrawString(fmt.Sprintf("%d", num), freetype.Pt(int(x), int(yPos+unitSize*7)))

	// Draw bars
	ds := toBase4(num, 9)
	for i := len(ds) - 1; i >= 0; i-- {
		x += drawBar(img, unitSize, x, yPos, ds[i]) + unitSize
	}

	// Draw checksum bars
	ckBase10 := csumGen(num)
	fmt.Println("ckBase10 = ", ckBase10)
	ck := toBase4(ckBase10, 2)
	fmt.Println("ck = ", ck)
	for i := len(ck) - 1; i >= 0; i-- {
		x += drawBar(img, unitSize, x, yPos, ck[i]) + unitSize
	}

}
Пример #6
0
func Example() {
	// As usual in examples, this ignores all errors. Don't do this in your program.

	// setup and find start point for centering
	s := "Hello, World!"
	size := image.Rect(0, 0, 120, 20)
	dst := image.NewRGBA(size)
	c := freetype.NewContext()
	c.SetFont(font)
	c.SetFontSize(14.0)
	c.SetSrc(image.NewUniform(color.Black))
	c.SetDst(dst)
	start, _ := fontutil.CenterX(c, s, size) // CenterX calls c.SetClip(size)

	// perform draw at start.X + y 16
	c.DrawString(s, start.Add(freetype.Pt(0, 16)))

	// write the image out to a file
	// out, _ := os.Create("helloworld.png")
	// defer out.Close()

	// write image to hash for testing purposes
	out := fnv.New64()
	_ = png.Encode(out, dst)
	fmt.Printf("Hash of compressed image: %x", out.Sum64())
	// Output: Hash of compressed image: fa83a1b8d8abf5f2
}
Пример #7
0
func (ff *FontFace) GetImage(text string) (img draw.Image, err error) {
	var (
		src image.Image
		bg  image.Image
		dst draw.Image
		pt  fixed.Point26_6
		w   int
		h   int
	)
	src = image.NewUniform(ff.fg)
	bg = image.NewUniform(ff.bg)
	w = int(float32(len(text)) * ff.charw)
	h = int(ff.charh)
	dst = image.NewRGBA(image.Rect(0, 0, w, h))
	draw.Draw(dst, dst.Bounds(), bg, image.ZP, draw.Src)
	ff.context.SetSrc(src)
	ff.context.SetDst(dst)
	ff.context.SetClip(dst.Bounds())
	pt = freetype.Pt(0, int(ff.charh+ff.offy))
	if pt, err = ff.context.DrawString(text, pt); err != nil {
		return
	}
	img = image.NewRGBA(image.Rect(0, 0, int(pt.X/64), int(pt.Y/64)))
	draw.Draw(img, img.Bounds(), dst, image.Pt(0, -int(ff.offy)), draw.Src)
	return
}
Пример #8
0
func (a *Annotator) DrawInfoBox() error {

	tStart, tEnd := a.table.TimeStart, a.table.TimeEnd
	// tDuration := humanize.RelTime(*tStart, *tEnd, "", "")
	tPixel := (tEnd.Unix() - tStart.Unix()) / int64(a.table.Integrations)

	fStart, fEnd := a.table.HzLow, a.table.HzHigh
	fBandwidth := fEnd - fStart
	fPixel := fBandwidth / float64(a.table.Bins)

	perPixel := fmt.Sprintf("%s x %d seconds", a.humanHz(fPixel), tPixel)

	// positioning
	imgSize := a.table.Image().Bounds().Size()
	top, left := imgSize.Y-75, 3

	strings := []string{
		"Scan start: " + tStart.String(),
		"Scan end: " + tEnd.String(),
		// "Scan duration: " + tDuration,
		fmt.Sprintf("Band: %s to %s", a.humanHz(fStart), a.humanHz(fEnd)),
		fmt.Sprintf("Bandwidth: %s", a.humanHz(fBandwidth)),
		"1 pixel = " + perPixel,
	}

	// drawing
	pt := freetype.Pt(left, top)
	for _, s := range strings {
		_, _ = a.context.DrawString(s, pt)
		pt.Y += a.context.PointToFixed(size * spacing)
	}

	return nil
}
Пример #9
0
func (ff *FontFace) GetText(text string) (t *Texture, err error) {
	var (
		src       image.Image
		bg        image.Image
		dst       draw.Image
		shortened draw.Image
		pt        fixed.Point26_6
		w         int
		h         int
	)
	src = image.NewUniform(ff.fg)
	bg = image.NewUniform(ff.bg)
	w = int(float32(len(text)) * ff.charw)
	h = int(ff.charh)
	dst = image.NewRGBA(image.Rect(0, 0, w, h))
	draw.Draw(dst, dst.Bounds(), bg, image.ZP, draw.Src)
	ff.context.SetSrc(src)
	ff.context.SetDst(dst)
	ff.context.SetClip(dst.Bounds())
	pt = freetype.Pt(0, int(ff.charh))
	if pt, err = ff.context.DrawString(text, pt); err != nil {
		return
	}
	// if err = WritePNG("hello.png", dst); err != nil {
	// 	return
	// }
	shortened = image.NewRGBA(image.Rect(0, 0, int(pt.X/64), h))
	draw.Draw(shortened, shortened.Bounds(), dst, image.ZP, draw.Src)
	t, err = GetTexture(shortened, gl.NEAREST)
	return
}
Пример #10
0
Файл: nope.go Проект: nf/nope
func main() {
	fontBytes, err := ioutil.ReadFile("luxisr.ttf")
	if err != nil {
		log.Fatal(err)
	}
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		log.Fatal(err)
	}

	fg, bg := image.White, image.Black
	rgba := image.NewRGBA(image.Rect(0, 0, width, height))
	draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)
	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(font)
	c.SetFontSize(size)
	c.SetClip(rgba.Bounds())
	c.SetDst(rgba)
	c.SetSrc(fg)
	c.SetHinting(freetype.FullHinting)

	count := 0
	l := NewLife(width, height)
	for {
		if count%10 == 0 {
			count = 0
			pt := freetype.Pt(rand.Intn(width-width/4), height/4+rand.Intn(height-height/4))
			c.DrawString("NOPE", pt)
			for x := 0; x < width; x++ {
				for y := 0; y < height; y++ {
					c := rgba.RGBAAt(x, y)
					l.a.Set(x, y, c.R > 0 || c.B > 0 || c.G > 0)
				}
			}
		}
		count++

		for x := 0; x < width; x++ {
			for y := 0; y < height; y++ {
				var c color.Color = color.Black
				if l.a.Alive(x, y) {
					c = rainbow(y)
				}
				rgba.Set(x, y, c)
			}
		}

		//fmt.Println(l)
		sendImage(rgba)
		l.Step()

		time.Sleep(time.Second / 8)
	}
}
Пример #11
0
func (w *TextEditLine) findOffsetAtIndex(index int) float64 {
	pt := freetype.Pt(0, 0)
	if index > len(w.text) {
		index = len(w.text)
	}
	if index < 0 {
		index = 0
	}
	adv, _ := w.context.DrawString(w.text[:index], pt)
	return float64(adv.X>>8) * w.scale
}
Пример #12
0
func (a *Annotator) DrawYScale() error {

	log.WithFields(log.Fields{
		"timestart": a.table.TimeStart.String(),
		"timeend":   a.table.TimeEnd.String(),
	}).Debug("annotate Y scale")

	start, end := a.table.TimeStart, a.table.TimeEnd

	// how many samples?
	count := int(math.Floor(float64(a.table.Integrations) / float64(100)))

	uStart := start.Unix()
	uEnd := end.Unix()

	secsPerLabel := int(math.Floor(float64(uEnd-uStart) / float64(count)))
	pxPerLabel := int(math.Floor(float64(a.table.Integrations) / float64(count)))

	log.WithFields(log.Fields{
		"labels":       count,
		"secsPerLabel": secsPerLabel,
		"pxPerLabel":   pxPerLabel,
	}).Debug("annotate Y scale")

	for si := 0; si < count; si++ {

		secs := time.Duration(secsPerLabel * si * int(time.Second))
		px := si * pxPerLabel

		var str string = ""

		if si == 0 {
			str = start.String()
		} else {
			point := start.Add(secs)
			str = point.Format("15:04:05")
		}

		// draw a guideline on the exact time
		for i := 0; i < 75; i++ {
			a.image.Set(i, px, image.White)
		}

		// draw the text, 3 px margin to the line
		pt := freetype.Pt(3, px-3)
		_, _ = a.context.DrawString(str, pt)

	}

	return nil

}
Пример #13
0
// Write a text inside the image
func WriteText(text string, f *truetype.Font, img *image.Paletted) {
	// Initialize the context.
	fg := image.Black
	c := freetype.NewContext()
	c.SetDPI(72)
	c.SetFont(f)
	c.SetFontSize(64)
	c.SetClip(img.Bounds())
	c.SetDst(img)
	c.SetSrc(fg)
	// Draw the text.
	pt := freetype.Pt(40, 120)
	c.DrawString(text, pt)
}
Пример #14
0
func (ig *ImageGraphics) TextLen(s string, font chart.Font) int {
	c := freetype.NewContext()
	c.SetDPI(dpi)
	c.SetFont(ig.font)
	fontsize := ig.relFontsizeToPixel(font.Size)
	c.SetFontSize(fontsize)

	// really draw it
	width, err := c.DrawString(s, freetype.Pt(0, 0))
	if err != nil {
		return 10 * len(s) // BUG
	}
	return int(width.X+32)>>6 + 1
}
Пример #15
0
func (a Annotator) annotate(upperText string, lowerText string) []byte {
	fontColor, _ := colorful.Hex("#000000")
	fontMask := image.NewUniform(fontColor)

	templateFile, _ := ioutil.ReadFile("./static/template.jpg")
	srcImage, _ := jpeg.Decode(bytes.NewBuffer(templateFile))
	srcBounds := srcImage.Bounds()
	srcHeight := srcBounds.Max.Y

	imageMask := image.NewRGBA(srcBounds)
	imageMaskClip := imageMask.Bounds()
	draw.Draw(imageMask, imageMaskClip, srcImage, image.ZP, draw.Src)

	c := freetype.NewContext()
	c.SetFont(font)
	c.SetFontSize(60)
	c.SetDPI(60)
	c.SetSrc(fontMask)
	c.SetDst(imageMask)
	c.SetClip(imageMaskClip)

	drawLines := func(line string, point fixed.Point26_6) {
		c.DrawString(line, point)
	}

	upperPoint := freetype.Pt(10, 40)
	lowerPoint := freetype.Pt(10, srcHeight-10)

	drawLines(upperText, upperPoint)
	drawLines(lowerText, lowerPoint)

	dataBuffer := bytes.NewBuffer([]byte(""))
	jpeg.Encode(dataBuffer, imageMask, nil)

	return dataBuffer.Bytes()
}
Пример #16
0
func main() {
	imgcounter := 123
	imgfile, _ := os.Create(fmt.Sprintf("%03d.png", imgcounter))

	defer imgfile.Close()

	img := image.NewNRGBA(image.Rect(0, 0, dx, dy))

	for y := 0; y < dy; y++ {
		for x := 0; x < dx; x++ {
			img.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
		}
	}

	fontBytes, err := ioutil.ReadFile(fontFile) //读取字体数据
	if err != nil {
		fmt.Println(err)
		return
	}
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		fmt.Print(err)
		return
	}
	c := freetype.NewContext()
	c.SetDPI(fontDPI)
	c.SetFont(font)
	c.SetFontSize(fontSize)
	c.SetClip(img.Bounds())
	c.SetDst(img)
	c.SetSrc(image.White)
	pt := freetype.Pt(10, 10+int(c.PointToFixed(fontSize)>>8)) // 字出现的位置

	_, err = c.DrawString("ABCDE", pt)
	if err != nil {
		fmt.Println(err)
		return
	}
	err = png.Encode(imgfile, img)
	if err != nil {
		fmt.Println(err)
	}

}
Пример #17
0
func (t *Text) getMaxHeight() int {
	w, h := t.GetStringSize("|")
	bounds := image.Rect(0, 0, int(w>>6), int(h>>6))
	img := image.NewRGBA(bounds)

	ctx := freetype.NewContext()
	ctx.SetFont(t.font)
	ctx.SetFontSize(t.fontSize)
	ctx.SetSrc(&image.Uniform{t.fillColor})
	ctx.SetDst(img)
	ctx.SetClip(bounds)
	ctx.DrawString("|", freetype.Pt(0, int(t.fontSize)))

	var i = len(img.Pix) - 1
	for ; img.Pix[i] == 0; i-- {

	}

	return (i / img.Stride) + 1
}
Пример #18
0
func (this *Signer) mark(text string) (image.Image, error) {
	fontBytes, err := ioutil.ReadFile(this.fontPath)
	if err != nil {
		fmt.Println(err)
	}
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		fmt.Println(err)
	}

	//读取图片
	file, err := os.Open(this.srcImage)
	if err != nil {
		fmt.Println(err)
	}
	defer file.Close()
	img, err := jpeg.Decode(file)
	if err != nil {
		fmt.Println(err)
	}
	bounds := img.Bounds()
	nrgba := image.NewNRGBA(bounds)
	draw.Draw(nrgba, img.Bounds(), img, image.ZP, draw.Over)
	c := freetype.NewContext()
	c.SetDPI(this.dpi)
	c.SetFont(font)
	c.SetDst(nrgba)
	c.SetFontSize(this.fontSize)
	c.SetClip(nrgba.Bounds())
	c.SetSrc(image.White)

	pt := freetype.Pt(100, 100+int(c.PointToFixed(this.fontSize)>>8))
	for _, s := range strings.Split(text, "\r\n") {
		_, err = c.DrawString(s, pt)
		pt.Y += c.PointToFixed(12 * 1.5)

	}

	return nrgba, nil

}
Пример #19
0
func createTextImage(text string, fontSize int, color color.Color, f *truetype.Font) (*image.RGBA, float32, float32, error) {
	// 1 pt = 1/72 in, 72 dpi = 1 in
	const dpi = 72

	fg, bg := image.NewUniform(color), image.Transparent

	c := freetype.NewContext()
	c.SetFont(f)
	c.SetDPI(dpi)
	c.SetFontSize(float64(fontSize)) // points
	c.SetSrc(fg)
	c.SetHinting(font.HintingFull)

	// 1. Figure out maximum height so all text lines are the same height.
	// 2. Draw within small bounds to figure out bounds.
	// 3. Draw within final bounds.

	scale := c.PointToFixed(float64(fontSize)) // point to pixels
	rect := f.Bounds(scale)                    // scale is pixels of 1 em
	maxHeight := int(rect.Max.Y>>6) - int(rect.Min.Y>>6)

	var rgba *image.RGBA
	w, h := 10, maxHeight
	for i := 0; i < 2; i++ {
		rgba = image.NewRGBA(image.Rect(0, 0, w, h))
		draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src)

		c.SetClip(rgba.Bounds())
		c.SetDst(rgba)

		pt := freetype.Pt(0, int(scale>>6))
		end, err := c.DrawString(text, pt)
		if err != nil {
			return nil, 0, 0, err
		}

		w = int(end.X >> 6)
	}

	return rgba, float32(w), float32(h), nil
}
Пример #20
0
func drawText(img *image.RGBA, font *truetype.Font, color color.Color, x, y int, s string) error {
	var ptSize float64 = 12

	ctx := freetype.NewContext()
	ctx.SetDPI(72)
	ctx.SetFont(font)
	ctx.SetFontSize(ptSize)
	ctx.SetClip(img.Bounds())
	ctx.SetDst(img)
	ctx.SetSrc(image.NewUniform(color))
	ctx.SetHinting(img_font.HintingFull)

	width := int(widthOfString(font, ptSize, s))
	pt := freetype.Pt(x-width/2, y+int(int32(ctx.PointToFixed(ptSize))>>8)/2)
	_, err := ctx.DrawString(s, pt)
	if err != nil {
		return err
	}

	return nil
}
Пример #21
0
func TextToImage(text string, fontSize float64, fontFile string, fontColor color.Color) (image.Image, error) {
	lines := len(strings.Split(text, "\n"))
	maxLen := getMaxLen(text)
	margin := 10
	width := maxLen*int(fontSize) + margin*2
	height := int(fontSize)*lines + margin*2

	var fontDPI float64 = 72

	fontBytes, err := ioutil.ReadFile(fontFile)
	if err != nil {
		return nil, err
	}
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		return nil, err
	}

	bg := image.Transparent

	newImg := image.NewRGBA(image.Rect(0, 0, width, height))
	draw.Draw(newImg, newImg.Bounds(), bg, image.ZP, draw.Src)
	c := freetype.NewContext()
	c.SetDPI(fontDPI)
	c.SetFont(font)
	c.SetFontSize(fontSize)
	c.SetClip(newImg.Bounds())
	c.SetDst(newImg)
	c.SetSrc(image.NewUniform(fontColor))
	// Draw the text.
	for i, s := range strings.Split(text, "\n") {
		Y := int(fontSize) + i*int(fontSize)
		pt := freetype.Pt(margin, Y)
		_, err := c.DrawString(s, pt)
		if err != nil {
			return nil, err
		}
	}
	return newImg, nil
}
Пример #22
0
func (a *Annotator) DrawXScale() error {

	log.WithFields(log.Fields{
		"hzHigh": humanize.SI(a.table.HzHigh, "Hz"),
		"hzLow":  humanize.SI(a.table.HzLow, "Hz"),
	}).Debug("annotate X scale")

	// how many samples?
	count := int(math.Floor(float64(a.table.Bins) / float64(350)))

	hzPerLabel := float64(a.table.HzHigh-a.table.HzLow) / float64(count)
	pxPerLabel := int(math.Floor(float64(a.table.Bins) / float64(count)))

	log.WithFields(log.Fields{
		"labels":     count,
		"hzPerLabel": humanize.SI(hzPerLabel, "Hz"),
		"pxPerLabel": pxPerLabel,
	}).Debug("annotate X scale")

	for si := 0; si < count; si++ {

		hz := a.table.HzLow + (float64(si) * hzPerLabel)
		px := si * pxPerLabel

		fract, suffix := humanize.ComputeSI(hz)
		str := fmt.Sprintf("%0.2f %sHz", fract, suffix)

		// draw a guideline on the exact frequency
		for i := 0; i < 30; i++ {
			a.image.Set(px, i, image.White)
		}

		// draw the text
		pt := freetype.Pt(px+5, 17)
		_, _ = a.context.DrawString(str, pt)

	}

	return nil
}
Пример #23
0
func (font *Font) createTexture(text string, width int, height int, size float64, dpi float64, rgba color.Color) (uint32, int, int) {
	context := freetype.NewContext()
	context.SetFont(font.ttf)

	img := image.NewRGBA(image.Rect(0, 0, width, height))
	r, g, b, _ := rgba.RGBA()
	draw.Draw(img, img.Bounds(), image.NewUniform(color.RGBA{uint8(r), uint8(g), uint8(b), 0}), image.ZP, draw.Src)

	context.SetDst(img)
	context.SetClip(img.Bounds())
	context.SetSrc(image.NewUniform(rgba))
	context.SetFontSize(size)
	context.SetDPI(dpi)
	pixelBounds, _ := context.DrawString(text, freetype.Pt(0, height/2))

	var tex uint32
	gl.GenTextures(1, &tex)
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, tex)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, tex)

	gl.TexImage2D(
		gl.TEXTURE_2D,
		0,
		gl.RGBA,
		int32(img.Rect.Size().X),
		int32(img.Rect.Size().Y),
		0,
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		gl.Ptr(img.Pix))

	return tex, int26_6Ceiling(pixelBounds.X + 0x3f), int26_6Ceiling(pixelBounds.Y + 0x3f)
}
Пример #24
0
func drawBubble(img *image.Gray, xPos, yPos, width, height float64, content string, filled bool) {
	gapBeg := xPos + width/4.0
	gapEnd := xPos + width - width/4.0

	if filled {
		drawRect(img, black, xPos, yPos, width, height)
		return
	}

	ftContext.DrawString(content, freetype.Pt(int(gapBeg+width/6), int(yPos+height)))
	for w := xPos; w < xPos+width; w += 1.0 {
		if w >= gapBeg && w <= gapEnd {
			continue
		}
		img.SetGray(int(w), int(yPos), color.Gray{0x22})
		img.SetGray(int(w), int(yPos+height), color.Gray{0x22})
	}

	for h := yPos; h < yPos+height; h += 1.0 {
		img.SetGray(int(xPos), int(h), color.Gray{0x22})
		img.SetGray(int(xPos+width), int(h), color.Gray{0x22})
	}
}
Пример #25
0
func createProfileImage(username string, userId string) ([]byte, *model.AppError) {
	colors := []color.NRGBA{
		{197, 8, 126, 255},
		{227, 207, 18, 255},
		{28, 181, 105, 255},
		{35, 188, 224, 255},
		{116, 49, 196, 255},
		{197, 8, 126, 255},
		{197, 19, 19, 255},
		{250, 134, 6, 255},
		{227, 207, 18, 255},
		{123, 201, 71, 255},
		{28, 181, 105, 255},
		{35, 188, 224, 255},
		{116, 49, 196, 255},
		{197, 8, 126, 255},
		{197, 19, 19, 255},
		{250, 134, 6, 255},
		{227, 207, 18, 255},
		{123, 201, 71, 255},
		{28, 181, 105, 255},
		{35, 188, 224, 255},
		{116, 49, 196, 255},
		{197, 8, 126, 255},
		{197, 19, 19, 255},
		{250, 134, 6, 255},
		{227, 207, 18, 255},
		{123, 201, 71, 255},
	}

	h := fnv.New32a()
	h.Write([]byte(userId))
	seed := h.Sum32()

	initial := string(strings.ToUpper(username)[0])

	fontBytes, err := ioutil.ReadFile(utils.FindDir("web/static/fonts") + utils.Cfg.FileSettings.InitialFont)
	if err != nil {
		return nil, model.NewAppError("createProfileImage", "Could not create default profile image font", err.Error())
	}
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		return nil, model.NewAppError("createProfileImage", "Could not create default profile image font", err.Error())
	}

	width := int(utils.Cfg.FileSettings.ProfileWidth)
	height := int(utils.Cfg.FileSettings.ProfileHeight)
	color := colors[int64(seed)%int64(len(colors))]
	dstImg := image.NewRGBA(image.Rect(0, 0, width, height))
	srcImg := image.White
	draw.Draw(dstImg, dstImg.Bounds(), &image.Uniform{color}, image.ZP, draw.Src)
	size := float64((width + height) / 4)

	c := freetype.NewContext()
	c.SetFont(font)
	c.SetFontSize(size)
	c.SetClip(dstImg.Bounds())
	c.SetDst(dstImg)
	c.SetSrc(srcImg)

	pt := freetype.Pt(width/6, height*2/3)
	_, err = c.DrawString(initial, pt)
	if err != nil {
		return nil, model.NewAppError("createProfileImage", "Could not add user initial to default profile picture", err.Error())
	}

	buf := new(bytes.Buffer)

	if imgErr := png.Encode(buf, dstImg); imgErr != nil {
		return nil, model.NewAppError("createProfileImage", "Could not encode default profile image", imgErr.Error())
	} else {
		return buf.Bytes(), nil
	}
}
Пример #26
0
func transformCropAndResize(img image.Image, transformation *Transformation) (imgNew image.Image) {
	parameters := transformation.params
	width := parameters.width
	height := parameters.height
	gravity := parameters.gravity
	scale := parameters.scale

	imgWidth := img.Bounds().Dx()
	imgHeight := img.Bounds().Dy()

	// Scaling factor
	if parameters.cropping != CroppingModeKeepScale {
		width *= scale
		height *= scale
	}

	// Resize and crop
	switch parameters.cropping {
	case CroppingModeExact:
		imgNew = resize.Resize(uint(width), uint(height), img, resize.Bilinear)
	case CroppingModeAll:
		if float32(width)*(float32(imgHeight)/float32(imgWidth)) > float32(height) {
			// Keep height
			imgNew = resize.Resize(0, uint(height), img, resize.Bilinear)
		} else {
			// Keep width
			imgNew = resize.Resize(uint(width), 0, img, resize.Bilinear)
		}
	case CroppingModePart:
		var croppedRect image.Rectangle
		if float32(width)*(float32(imgHeight)/float32(imgWidth)) > float32(height) {
			// Whole width displayed
			newHeight := int((float32(imgWidth) / float32(width)) * float32(height))
			croppedRect = image.Rect(0, 0, imgWidth, newHeight)
		} else {
			// Whole height displayed
			newWidth := int((float32(imgHeight) / float32(height)) * float32(width))
			croppedRect = image.Rect(0, 0, newWidth, imgHeight)
		}

		topLeftPoint := calculateTopLeftPointFromGravity(gravity, croppedRect.Dx(), croppedRect.Dy(), imgWidth, imgHeight)
		imgDraw := image.NewRGBA(croppedRect)

		draw.Draw(imgDraw, croppedRect, img, topLeftPoint, draw.Src)
		imgNew = resize.Resize(uint(width), uint(height), imgDraw, resize.Bilinear)
	case CroppingModeKeepScale:
		// If passed in dimensions are bigger use those of the image
		if width > imgWidth {
			width = imgWidth
		}
		if height > imgHeight {
			height = imgHeight
		}

		croppedRect := image.Rect(0, 0, width, height)
		topLeftPoint := calculateTopLeftPointFromGravity(gravity, width, height, imgWidth, imgHeight)
		imgDraw := image.NewRGBA(croppedRect)

		draw.Draw(imgDraw, croppedRect, img, topLeftPoint, draw.Src)
		imgNew = imgDraw.SubImage(croppedRect)
	}

	// Filters
	if parameters.filter == FilterGrayScale {
		bounds := imgNew.Bounds()
		w, h := bounds.Max.X, bounds.Max.Y
		gray := image.NewGray(bounds)
		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				oldColor := imgNew.At(x, y)
				grayColor := color.GrayModel.Convert(oldColor)
				gray.Set(x, y, grayColor)
			}
		}
		imgNew = gray
	}

	if transformation.watermark != nil {
		w := transformation.watermark

		var watermarkSrcScaled image.Image
		var watermarkBounds image.Rectangle

		// Try to load a scaled watermark first
		if scale > 1 {
			scaledPath, err := constructScaledPath(w.imagePath, scale)
			if err != nil {
				log.Println("Error:", err)
				return
			}

			watermarkSrc, _, err := loadImage(scaledPath)
			if err != nil {
				log.Println("Error: could not load a watermark", err)
			} else {
				watermarkBounds = watermarkSrc.Bounds()
				watermarkSrcScaled = watermarkSrc
			}
		}

		if watermarkSrcScaled == nil {
			watermarkSrc, _, err := loadImage(w.imagePath)
			if err != nil {
				log.Println("Error: could not load a watermark", err)
				return
			}
			watermarkBounds = image.Rect(0, 0, watermarkSrc.Bounds().Max.X*scale, watermarkSrc.Bounds().Max.Y*scale)
			watermarkSrcScaled = resize.Resize(uint(watermarkBounds.Max.X), uint(watermarkBounds.Max.Y), watermarkSrc, resize.Bilinear)
		}

		bounds := imgNew.Bounds()

		// Make sure we have a transparent watermark if possible
		watermark := image.NewRGBA(watermarkBounds)
		draw.Draw(watermark, watermarkBounds, watermarkSrcScaled, watermarkBounds.Min, draw.Src)

		pt := calculateTopLeftPointFromGravity(w.gravity, watermarkBounds.Dx(), watermarkBounds.Dy(), bounds.Dx(), bounds.Dy())
		pt = pt.Add(getTranslation(w.gravity, w.x*scale, w.y*scale))
		wX := pt.X
		wY := pt.Y

		watermarkRect := image.Rect(wX, wY, watermarkBounds.Dx()+wX, watermarkBounds.Dy()+wY)
		finalImage := image.NewRGBA(bounds)
		draw.Draw(finalImage, bounds, imgNew, bounds.Min, draw.Src)
		draw.Draw(finalImage, watermarkRect, watermark, watermarkBounds.Min, draw.Over)
		imgNew = finalImage.SubImage(bounds)
	}

	if transformation.texts != nil {
		bounds := imgNew.Bounds()
		rgba := image.NewRGBA(bounds)
		draw.Draw(rgba, bounds, imgNew, image.ZP, draw.Src)

		dpi := float64(72) // Multiply this by scale for a baaad time

		c := freetype.NewContext()
		c.SetDPI(dpi)
		c.SetClip(rgba.Bounds())
		c.SetDst(rgba)

		for _, text := range transformation.texts {
			size := float64(text.size * scale)

			c.SetSrc(image.NewUniform(text.color))
			c.SetFont(text.font)
			c.SetFontSize(size)

			fontMetrics := text.getFontMetrics(scale)
			width := int(c.PointToFix32(fontMetrics.width) >> 8)
			height := int(c.PointToFix32(fontMetrics.height) >> 8)

			pt := calculateTopLeftPointFromGravity(text.gravity, width, height, bounds.Dx(), bounds.Dy())
			pt = pt.Add(getTranslation(text.gravity, text.x*scale, text.y*scale))
			x := pt.X
			y := pt.Y + int(c.PointToFix32(fontMetrics.ascent)>>8)

			_, err := c.DrawString(text.content, freetype.Pt(x, y))
			if err != nil {
				log.Println("Error adding text:", err)
				return
			}
		}

		imgNew = rgba
	}

	return
}
Пример #27
0
func main() {
	rightFile, err := os.Open("p1.jpg")
	if err != nil {
		panic(err)
	}

	rightPortrait, err := jpeg.Decode(rightFile)
	if err != nil {
		panic(err)
	}

	leftFile, err := os.Open("p2.jpg")
	if err != nil {
		panic(err)
	}

	leftPortrait, err := jpeg.Decode(leftFile)
	if err != nil {
		panic(err)
	}

	rightImage := resize.Resize(400, 600, rightPortrait, resize.Bilinear)
	leftImage := resize.Resize(400, 600, leftPortrait, resize.Bilinear)

	t, err := os.Open("template.png")
	if err != nil {
		panic(err)
	}
	mask, err := png.Decode(t)
	if err != nil {
		panic(err)
	}

	newImage := image.NewRGBA(rightImage.Bounds())
	draw.Draw(newImage, rightImage.Bounds(), rightImage, image.ZP, draw.Src)
	draw.DrawMask(newImage, leftImage.Bounds(), leftImage, image.ZP, mask, image.ZP, draw.Over)

	ctx := freetype.NewContext()
	ctx.SetFont(strokeFont)
	ctx.SetFontSize(84)
	ctx.SetSrc(image.Black)
	ctx.SetDst(newImage)
	ctx.SetClip(newImage.Bounds())
	_, err = ctx.DrawString("TOGETHER", freetype.Pt(40, 200))
	if err != nil {
		panic(err)
	}

	ctx.SetFont(posterFont)
	ctx.SetFontSize(12)
	ctx.SetSrc(image.White)
	ctx.SetDst(newImage)
	ctx.SetClip(newImage.Bounds())
	_, err = ctx.DrawString("#VOTETOGETHER", freetype.Pt(150, 580))
	if err != nil {
		panic(err)
	}

	f, err := os.Create("newimage.png")
	if err != nil {
		panic(err)
	}
	defer f.Close()

	err = png.Encode(f, newImage)
	if err != nil {
		panic(err)
	}
}
Пример #28
0
func tryLoadFont(fontFilePath string) (Font, error) {
	defer tlog.FuncLog(tlog.Func("LoadFont"))
	var data []byte
	{
		fd, err := os.Open(fontFilePath)
		if err != nil {
			return Font{}, err
		}
		defer fd.Close()

		data, err = ioutil.ReadAll(fd)
		if err != nil {
			return Font{}, err
		}
	}

	texsdfpath := filepath.Join(os.TempDir(), filepath.Base(fontFilePath)+".sdf")
	texsdf, err := LoadPng(texsdfpath)
	sdfLoaded := err == nil
	if err != nil {
		texsdf = image.NewGray(image.Rect(0, 0, texSize, texSize))
	}
	name := filepath.Base(fontFilePath)
	name = name[:len(name)-len(filepath.Ext(name))]

	var f = Font{
		SdfTex:    texsdf,
		Glyphs:    make([]Glyph, int(highRune-lowRune+1)),
		FirstRune: lowRune,
		Name:      name,
		Height:    0,
		Leading:   0,
	}

	{
		// Read the truetype font.
		ttf, err := truetype.Parse(data)
		if err != nil {
			return Font{}, err
		}

		var baseline = 3 * sdfSize / 4
		var targetGlyphExtentPxs = float64(sdfSize) * 3.0 / 4.0
		var fontHeight float64    // maximum height, in renormalized EMs
		var renormalizeEM float64 // (real max glyph size / em)
		{
			// the real max glyph extent in EMs
			var maxGlyphExtentEMs float64
			{
				var max fixed.Int26_6    // = 0; max extent(height or width) of a glyph in FontUnits
				var height fixed.Int26_6 // = 0; max height of a glyph in FontUnits
				{
					scale := fixed.I(int(ttf.FUnitsPerEm()))
					b := ttf.Bounds(scale)
					max = b.Max.X - b.Min.X
					height = b.Max.Y - b.Min.Y
					if max < height {
						max = height
					}
					for ch := lowRune; ch <= highRune; ch++ {
						hmetric := ttf.HMetric(scale, ttf.Index(ch))
						vmetric := ttf.VMetric(scale, ttf.Index(ch))
						if max < hmetric.AdvanceWidth {
							max = hmetric.AdvanceWidth
						}
						if height < vmetric.AdvanceHeight {
							height = vmetric.AdvanceHeight
						}
						if max < height {
							max = height
						}
					}
				}
				maxGlyphExtentEMs = float64(max) / float64(ttf.FUnitsPerEm())
				fontHeight = float64(height) / float64(ttf.FUnitsPerEm())
			}
			renormalizeEM = 1 / maxGlyphExtentEMs
			fontHeight *= renormalizeEM
		}
		f.Height = em(fontHeight)
		f.Leading = em(leadingFactor * fontHeight)
		scale := fixed.I(int(ttf.FUnitsPerEm()))

		graphicIdx := 0
		for ch := lowRune; ch <= highRune; ch++ {
			// fmt.Printf("%c", ch)

			idx := int(ch - lowRune)

			var aw float64
			{
				hmetric := ttf.HMetric(scale, ttf.Index(ch))
				aw = float64(hmetric.AdvanceWidth) / float64(ttf.FUnitsPerEm()) * renormalizeEM
				f.Glyphs[idx].AdvanceWidth = em(aw)
			}

			if !unicode.IsGraphic(ch) || unicode.IsSpace(ch) {
				f.Glyphs[idx].Cell = image.ZR
				continue
			}

			x0 := cellSize * (graphicIdx % texNCells)
			y0 := cellSize * (graphicIdx / texNCells)
			graphicIdx++
			f.Glyphs[idx].Cell = image.Rect(x0, y0, x0+cellSize, y0+cellSize)

			sdfTargetWidth := targetGlyphExtentPxs * aw
			sdfTargetHeight := targetGlyphExtentPxs * fontHeight

			if !sdfLoaded {
				img := image.NewGray(image.Rect(0, 0, sdfSize, sdfSize))
				c := freetype.NewContext()
				c.SetFont(ttf)
				c.SetDPI(72)                                        // so that one Pt == one Pixel
				c.SetFontSize(targetGlyphExtentPxs * renormalizeEM) // how many Pt the max glyph has
				c.SetClip(img.Bounds())
				c.SetDst(img)
				c.SetSrc(image.White)

				sdfX := (sdfSize - int(sdfTargetWidth)) / 2
				c.DrawString(string(ch), freetype.Pt(sdfX, baseline))
				sdfize(img)
				scaleDownTo(f.SdfTex, f.Glyphs[idx].Cell, img)
			}

			dx := (sdfSize - int(sdfTargetWidth)) / 2 * cellSize / sdfSize
			cellHeight := sdfTargetHeight * float64(cellSize) / float64(sdfSize)
			dy := (cellSize - int(cellHeight)) / 4

			f.Glyphs[idx].Cell = image.Rect(x0+dx, y0+3*dy, x0+cellSize-dx, y0+cellSize-dy)
			// drawRect(f.SdfTex, f.Glyphs[idx].Cell, color.Gray{255})
		}
	}

	if !sdfLoaded {
		SavePng(texsdfpath, f.SdfTex)
		tlog.Println("sdf ", texsdfpath, " saved")
	}
	// ShowImage(f.SdfTex)
	tlog.Println(fontFilePath, " loaded")
	return f, nil
}
Пример #29
-1
func makeImage(req *http.Request, caption, font string, pt, size, border, scale int, f func(x, y int) uint32) *image.RGBA {
	d := (size + 2*border) * scale
	csize := 0
	if caption != "" {
		if pt == 0 {
			pt = 11
		}
		csize = pt * 2
	}
	c := image.NewRGBA(image.Rect(0, 0, d, d+csize))

	// white
	u := &image.Uniform{C: color.White}
	draw.Draw(c, c.Bounds(), u, image.ZP, draw.Src)

	for y := 0; y < size; y++ {
		for x := 0; x < size; x++ {
			r := image.Rect((x+border)*scale, (y+border)*scale, (x+border+1)*scale, (y+border+1)*scale)
			rgba := f(x, y)
			u.C = color.RGBA{byte(rgba >> 24), byte(rgba >> 16), byte(rgba >> 8), byte(rgba)}
			draw.Draw(c, r, u, image.ZP, draw.Src)
		}
	}

	if csize != 0 {
		if font == "" {
			font = "data/luxisr.ttf"
		}
		ctxt := fs.NewContext(req)
		dat, _, err := ctxt.Read(font)
		if err != nil {
			panic(err)
		}
		tfont, err := freetype.ParseFont(dat)
		if err != nil {
			panic(err)
		}
		ft := freetype.NewContext()
		ft.SetDst(c)
		ft.SetDPI(100)
		ft.SetFont(tfont)
		ft.SetFontSize(float64(pt))
		ft.SetSrc(image.NewUniform(color.Black))
		ft.SetClip(image.Rect(0, 0, 0, 0))
		wid, err := ft.DrawString(caption, freetype.Pt(0, 0))
		if err != nil {
			panic(err)
		}
		p := freetype.Pt(d, d+3*pt/2)
		p.X -= wid.X
		p.X /= 2
		ft.SetClip(c.Bounds())
		ft.DrawString(caption, p)
	}

	return c
}
Пример #30
-1
func (font *Font) updateTexture(texture uint32, text string, width int, height int, size float64, dpi float64, rgba color.Color) (int, int) {
	context := freetype.NewContext()
	context.SetFont(font.ttf)

	img := image.NewRGBA(image.Rect(0, 0, width, height))
	r, g, b, _ := rgba.RGBA()
	draw.Draw(img, img.Bounds(), image.NewUniform(color.RGBA{uint8(r), uint8(g), uint8(b), 0}), image.ZP, draw.Src)

	context.SetDst(img)
	context.SetClip(img.Bounds())
	context.SetSrc(image.NewUniform(rgba))
	context.SetFontSize(size)
	context.SetDPI(dpi)
	pixelBounds, _ := context.DrawString(text, freetype.Pt(0, height/2))

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, texture)

	gl.TexSubImage2D(
		gl.TEXTURE_2D,
		0,
		0,
		0,
		int32(img.Rect.Size().X),
		int32(img.Rect.Size().Y),
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		gl.Ptr(img.Pix))

	return int26_6Ceiling(pixelBounds.X + 0x3f), int26_6Ceiling(pixelBounds.Y + 0x3f)
}