Giter Site home page Giter Site logo

gg's Introduction

Go Graphics

gg is a library for rendering 2D graphics in pure Go.

Stars

Installation

go get -u github.com/fogleman/gg

Alternatively, you may use gopkg.in to grab a specific major-version:

go get -u gopkg.in/fogleman/gg.v1

Documentation

Hello, Circle!

Look how easy!

package main

import "github.com/fogleman/gg"

func main() {
    dc := gg.NewContext(1000, 1000)
    dc.DrawCircle(500, 500, 400)
    dc.SetRGB(0, 0, 0)
    dc.Fill()
    dc.SavePNG("out.png")
}

Examples

There are lots of examples included. They're mostly for testing the code, but they're good for learning, too.

Examples

Creating Contexts

There are a few ways of creating a context.

NewContext(width, height int) *Context
NewContextForImage(im image.Image) *Context
NewContextForRGBA(im *image.RGBA) *Context

Drawing Functions

Ever used a graphics library that didn't have functions for drawing rectangles or circles? What a pain!

DrawPoint(x, y, r float64)
DrawLine(x1, y1, x2, y2 float64)
DrawRectangle(x, y, w, h float64)
DrawRoundedRectangle(x, y, w, h, r float64)
DrawCircle(x, y, r float64)
DrawArc(x, y, r, angle1, angle2 float64)
DrawEllipse(x, y, rx, ry float64)
DrawEllipticalArc(x, y, rx, ry, angle1, angle2 float64)
DrawRegularPolygon(n int, x, y, r, rotation float64)
DrawImage(im image.Image, x, y int)
DrawImageAnchored(im image.Image, x, y int, ax, ay float64)
SetPixel(x, y int)

MoveTo(x, y float64)
LineTo(x, y float64)
QuadraticTo(x1, y1, x2, y2 float64)
CubicTo(x1, y1, x2, y2, x3, y3 float64)
ClosePath()
ClearPath()
NewSubPath()

Clear()
Stroke()
Fill()
StrokePreserve()
FillPreserve()

It is often desired to center an image at a point. Use DrawImageAnchored with ax and ay set to 0.5 to do this. Use 0 to left or top align. Use 1 to right or bottom align. DrawStringAnchored does the same for text, so you don't need to call MeasureString yourself.

Text Functions

It will even do word wrap for you!

DrawString(s string, x, y float64)
DrawStringAnchored(s string, x, y, ax, ay float64)
DrawStringWrapped(s string, x, y, ax, ay, width, lineSpacing float64, align Align)
MeasureString(s string) (w, h float64)
MeasureMultilineString(s string, lineSpacing float64) (w, h float64)
WordWrap(s string, w float64) []string
SetFontFace(fontFace font.Face)
LoadFontFace(path string, points float64) error

Color Functions

Colors can be set in several different ways for your convenience.

SetRGB(r, g, b float64)
SetRGBA(r, g, b, a float64)
SetRGB255(r, g, b int)
SetRGBA255(r, g, b, a int)
SetColor(c color.Color)
SetHexColor(x string)

Stroke & Fill Options

SetLineWidth(lineWidth float64)
SetLineCap(lineCap LineCap)
SetLineJoin(lineJoin LineJoin)
SetDash(dashes ...float64)
SetDashOffset(offset float64)
SetFillRule(fillRule FillRule)

Gradients & Patterns

gg supports linear, radial and conic gradients and surface patterns. You can also implement your own patterns.

SetFillStyle(pattern Pattern)
SetStrokeStyle(pattern Pattern)
NewSolidPattern(color color.Color)
NewLinearGradient(x0, y0, x1, y1 float64)
NewRadialGradient(x0, y0, r0, x1, y1, r1 float64)
NewConicGradient(cx, cy, deg float64)
NewSurfacePattern(im image.Image, op RepeatOp)

Transformation Functions

Identity()
Translate(x, y float64)
Scale(x, y float64)
Rotate(angle float64)
Shear(x, y float64)
ScaleAbout(sx, sy, x, y float64)
RotateAbout(angle, x, y float64)
ShearAbout(sx, sy, x, y float64)
TransformPoint(x, y float64) (tx, ty float64)
InvertY()

It is often desired to rotate or scale about a point that is not the origin. The functions RotateAbout, ScaleAbout, ShearAbout are provided as a convenience.

InvertY is provided in case Y should increase from bottom to top vs. the default top to bottom.

Stack Functions

Save and restore the state of the context. These can be nested.

Push()
Pop()

Clipping Functions

Use clipping regions to restrict drawing operations to an area that you defined using paths.

Clip()
ClipPreserve()
ResetClip()
AsMask() *image.Alpha
SetMask(mask *image.Alpha)
InvertMask()

Helper Functions

Sometimes you just don't want to write these yourself.

Radians(degrees float64) float64
Degrees(radians float64) float64
LoadImage(path string) (image.Image, error)
LoadPNG(path string) (image.Image, error)
SavePNG(path string, im image.Image) error

Separator

Another Example

See the output of this example below.

package main

import "github.com/fogleman/gg"

func main() {
	const S = 1024
	dc := gg.NewContext(S, S)
	dc.SetRGBA(0, 0, 0, 0.1)
	for i := 0; i < 360; i += 15 {
		dc.Push()
		dc.RotateAbout(gg.Radians(float64(i)), S/2, S/2)
		dc.DrawEllipse(S/2, S/2, S*7/16, S/8)
		dc.Fill()
		dc.Pop()
	}
	dc.SavePNG("out.png")
}

Ellipses

gg's People

Contributors

ajnirp avatar bevand10 avatar emaele avatar flopp avatar fogleman avatar jamiecrisman avatar kortschak avatar magneticcoffee avatar mazznoer avatar odeke-em avatar rekby avatar tschaub avatar wsw0108 avatar xeoncross avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gg's Issues

concurrent use of MeasureString causes panic

The following program panics consistently for me:

package main

import (
	"fmt"
	"strconv"
	"sync"

	"golang.org/x/image/font"

	"github.com/fogleman/gg"
)

var face font.Face

func main() {
	f, err := gg.LoadFontFace("/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", 12)
	if err != nil {
		panic(err)
	}
	face = f

	var wg sync.WaitGroup

	for i := 0; i < 100; i++ {
		wg.Add(1)
		go func() {
			drawIt(i)
			wg.Done()
		}()
	}

	wg.Wait()
}

func drawIt(id int) {
	for i := 0; i < 100; i++ {
		gctx := gg.NewContext(1000, 1000)
		gctx.SetFontFace(face)

		w, h := gctx.MeasureString(strconv.Itoa(i))
		fmt.Printf("%02d %d %f %f\n", id, i, w, h)
	}
}

The panic is:

panic: runtime error: index out of range

goroutine 58 [running]:
vendor/github.com/golang/freetype/truetype.(*GlyphBuf).load(0xc42009eb00, 0x1001600000000, 0xc400000033, 0x16)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/github.com/golang/freetype/truetype/glyph.go:231 +0x70e
vendor/github.com/golang/freetype/truetype.(*GlyphBuf).Load(0xc42009eb00, 0xc4200103c0, 0x1600000300, 0x0, 0x40bdc8, 0x4ea420)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/github.com/golang/freetype/truetype/glyph.go:102 +0xd2
vendor/github.com/golang/freetype/truetype.(*face).GlyphAdvance(0xc42009c000, 0x33, 0x0)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/github.com/golang/freetype/truetype/face.go:345 +0x6e
vendor/golang.org/x/image/font.MeasureString(0x579a80, 0xc42009c000, 0xc4236b8122, 0x1, 0x3)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/golang.org/x/image/font/font.go:287 +0x84
vendor/golang.org/x/image/font.(*Drawer).MeasureString(0xc420c96eb0, 0xc4236b8122, 0x1, 0xc4236b8122)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/golang.org/x/image/font/font.go:201 +0x4c
vendor/github.com/fogleman/gg.(*Context).MeasureString(0xc420058500, 0xc4236b8122, 0x1, 0x4, 0x4)
        /home/psanford/projects/nearbuy/storenet/go/src/vendor/github.com/fogleman/gg/context.go:696 +0x88
main.drawIt(0x64)
        /home/psanford/projects/nearbuy/storenet/go/src/pms/fontsafe/main.go:47 +0xb1
main.main.func1(0xc42000e3e0, 0xc42000e3d0)
        /home/psanford/projects/nearbuy/storenet/go/src/pms/fontsafe/main.go:34 +0x2e
created by main.main
        /home/psanford/projects/nearbuy/storenet/go/src/pms/fontsafe/main.go:36 +0x108
exit status 2

According to https://godoc.org/golang.org/x/image/font#Face "A Face is not safe for concurrent use by multiple goroutines, as its methods may re-use implementation-specific caches and mask image buffers."

At the very least it seems like the package level LoadFontFace should say that it is not safe for concurrent use.

Memory optimization

Hello,

I've been working on optimizing the memory of an application I am working on, and I noticed that the context.Fill method creates a new Rasterizer each time it is called. This probably isn't noticeable in most use cases, but in my case the rendering is being used very heavily, and I noticed a lot of the memory allocation in my application came from this method:

https://github.com/fogleman/gg/blob/master/context.go#L397

Would it be possible to reuse the rasterizer for multiple calls to Fill ?

Question: How to draw a point ?

I used DrawCircle to draw a point, but the point was scaled.

func main() {
	dc := gg.NewContext(300, 300)

	dc.SetRGB(1, 1, 1)
	dc.Clear()
	dc.SetRGB(0, 0, 0)

	dc.Scale(5, .1)

	n := 100.0
	r := 1.0
	for i := 1.0; i < n; i++ {
		dc.DrawCircle(i, i, r)             // DrawPoint
		dc.DrawCircle(i, i*i, r)           // DrawPoint
		dc.DrawCircle(i, i*math.Log(i), r) // DrawPoint
	}
	dc.Fill()

	dc.SavePNG("out.png")
}

out

Can I erase something after drew?

Hi,
How can I erase something after drew?
example:
step1. draw a bezier stroke
step2. draw a Rectangle
step3. erase stroke that I drew in step1.

Thanks.

Opition to turn anti-aliasing off ?

Anti-aliasing makes pictures very larger, in some contexts, smaller is better. For example, a captcha gg generated is 8x larger than gd.

go-gg

captcha-go-gg

php-gd

captcha-php-gd

context.SetDashOffset not included in the v1.2.0 zip

I tried pulling in fogleman/gg as a dependency of gonum/plot but I'm running into a compile error because the SetDashOffset method is not included in the v1.2.0 release zip or tar. It looks like the commit is included in the history but the method is missing in the gofile. Can you fix this? @fogleman

Error in MeasureString for multiline strings

When I split line with newline symbol: It doesn't add in height, but increase width.

func test() {
	font := LoadFont()
	fontFace := truetype.NewFace(font, &truetype.Options{
		Size: 20,
	})

	ggContext := gg.NewContext(1000, 1000)

	ggContext.SetFontFace(fontFace)
	text1 := "asd asd"
	text2 := "asd\nasd"
	w1, h1 := ggContext.MeasureString(text1)
	w2, h2 := ggContext.MeasureString(text2)
	fmt.Printf("W1: %v, H1: %v\n", w1, h1)
	fmt.Printf("W2: %v, H2: %v\n", w2, h2)
}

I have output:

W1: 50, H1: 20
W2: 58, H2: 20

font height inconsistent between SetFontFace and LoadFontFace

context.LoadFontFace and context.SetFontFace can set different fontHeights:

package main

import (
	"fmt"

	"github.com/fogleman/gg"
)

func main() {
	text := "1234"

	font := "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf"
	face, err := gg.LoadFontFace(font, 12)
	if err != nil {
		panic(err)
	}

	gctx := gg.NewContext(128, 128)
	gctx.SetFontFace(face)
	_, h := gctx.MeasureString(text)
	fmt.Printf("set font face measured height=%f\n", h)

	err = gctx.LoadFontFace(font, 12)
	if err != nil {
		panic(err)
	}
	_, h = gctx.MeasureString(text)
	fmt.Printf("set load face measured height=%f\n", h)
}

This produces the following output:

set font face measured height=12.000000
set load face measured height=9.000000

I'm trying to draw a circle around some text. When I use LoadFontFace the text appears centered in the circle. When I use SetFontFace it appears slightly off.

Draw clock with using DrawArc provide unexpected result

I start implement clock widget and use your 2D render. My result is

image

I can not understand how to draw sector. I am start drawing from 150, 150 and call DrawArc.
It create path from 150, 150 to right draw arc and later I expect return back in 150, 150 but
I receive wrong join path. How to draw direct line.

Gradient filling problem

1.Radial gradient cannot be transformed
2.examples/gradient-linear.go
grad.AddColorStop(0, color.RGBA{0, 255, 0, 255}) to grad.AddColorStop(0, color.RGBA{0, 255, 0, 0})
color.RGBA.A !=255 has a problem

Bad MeasureString for multiline strings

When I split line with newline symbol: It doesn't add in height, but increase width.

func test() {
	font := LoadFont()
	fontFace := truetype.NewFace(font, &truetype.Options{
		Size: 20,
	})

	ggContext := gg.NewContext(1000, 1000)

	ggContext.SetFontFace(fontFace)
	text1 := "asd asd"
	text2 := "asd\nasd"
	w1, h1 := ggContext.MeasureString(text1)
	w2, h2 := ggContext.MeasureString(text2)
	fmt.Printf("W1: %v, H1: %v\n", w1, h1)
	fmt.Printf("W2: %v, H2: %v\n", w2, h2)
}

I have output:

W1: 50, H1: 20
W2: 58, H2: 20

Time for a new release?

The latest release, 1.0.0 doesn't handle image rotation correctly. This has been fixed in master, but pulling the latest tag will give you broken or old behaviour. I just spent quite a long time debugging inconsistent behaviour between my project and running the examples, only to find that dep will default to the latest tag, so I had to switch to the master branch manually.

Ignore stroke on the edge of image

Hi,
I am drawing a map tiles and I am ending up with edges of the image filled with stroke since it follows the path of a polygon to fill and stroke. When polygon overlaps the tile the edge of the image should not be stroked since it visually divides the polygon. So far I have tried to see if any edge of the image is filled with the same color that does not match the same line -1px inwards into the image but even with this fix I am still getting the edges which I think is the result of aliasing which accoridng to another issue cannot be turned on. So I wonder what would be a good way to disable stroke once on image's edge?

invert

See the grid - there is no grid, that's just the stroke following the path of the polygon. On the bottom left you can see it "fixed", the thin blue line, it is still there even with my fix.

PS: This is fix with transparent stroke on the edges - there is still a visible line.
transp

Solved by using draw2d library and setting fill rule to draw2d.FillRuleWinding with transparent border fix.

r.mask.AlphaAt undefined

I get the following error when attempting to go get this library.

go/src/github.com/fogleman/gg/pattern.go:101: r.mask.AlphaAt undefined (type *image.Alpha has no field or method AlphaAt)

Path docs clarification

Can you add, either in your README or in the godoc, an explanation of how ClearPath(), NewSubPath(), Fill(), and Trace() are intended to be used? Thank you.

Continue line stroke to the end of the edge - line cap

I am rendering a map and the paths(roads) are just lines so in order to make them thicker I had to use two strokes to simulate fill. This works without any issues and complex math for tessellation(at least I think that is what is used for this problem). The issue I am encountering is that the stroke will not continue to the edge of the image. Specifically, one side will turn inwards right before the edge of the image. When two opposing lines are rendered on two neighbouring images it creates visually broken path.

I am using rounded line cap, when I use butt the stroke will simply stop before reaching the edge. So obviously what is happening is that the original center of the line is reaching the edge of the image, yet the stroke continues a bit(outward side) until it reaches the 90 degree angle and stops. This if course happens only with some angles of the path. When this happens the rounding will take place(gg.LineCapRound) or nothgin. So the issue is that I need to prolong the stroke somehow.

Any idea how to fix this? One thing that comes to mind is somehow tricking the renderer to go past the edge of the image but am not sure how exactly.

zoom


I have fixed it by enlarging the image and drawing over it, then cropping it back to original size. But I wonder if aforementioned issue sohuldn't have a GG solution as well? Specifically, line cap setting that would make the stroke follow the edge where the end of the line actually ends. The outward stroke line already does it for rounded cap so there is a mechanism in place that could achieve this.

font loading errors are silently ignored

In method

func (dc *Context) LoadFontFace(path string, points float64)

Errors encountered when trying to load an invalid fontface path are silently ignored. It took me a couple of hours of changing up things as my font was always set to 13. It was not until I finally I edited the LoadFontFace code to log any errors that I was able to see the error, that I had passed in font path /Library/Fonts/Impact.tff instead of /Library/Fonts/Impact.ttf.

Please let me know what you think.

Transparant gradient problem

This code

        dc := gg.NewContext(300, 400)
	grad := gg.NewLinearGradient(0, 400, 0, 0)
	grad.AddColorStop(0, color.RGBA{30, 30, 200, 0})
	grad.AddColorStop(1, color.RGBA{30, 30, 200, 255})

	dc.SetFillStyle(grad)
	dc.MoveTo(0, 0)
	dc.LineTo(400, 0)
	dc.LineTo(400, 300)
	dc.LineTo(0, 300)
	dc.ClosePath()
	dc.Fill()

draws this image
out

Question: what contextcan it render to ?

Desktop using opengl ?
Windows, Linux, OSX ?
Maybe mobile ?

Then I am wondering about update speeds etc ?
If you out a game loop under it for example. Or is it really not designed for this ?

Could you please give me a example to scale image?

I'm not a old hand handle with image.
i just want to make a 1000 * 1000 pixel image to 100 * 100 pixel image.
with I Scale method didn't work and I can't find a example to do such thing.
Could you please just give me a snippet about it?

gg doesn't render rtl and bidi text correctly

There is some problem to render rtl languages text (like arabic, persian, kurdish, hebrew and ...) in gg.
The glypes doesnt render currectly.

Example:

package main

import (
    "github.com/fogleman/gg"
    "log"
)

func main() {
    const S = 1024
    im, err := gg.LoadImage("img.jpg")
    if err != nil {
        log.Fatal(err)
    }

    dc := gg.NewContext(S, S)
    dc.SetRGB(1, 1, 1)
    dc.Clear()
    dc.SetRGB(0, 0, 0)
    if err := dc.LoadFontFace("/home/dariush/Newsify/css/iransans/ttf/font.ttf", 96); err != nil {
        panic(err)
    }
    dc.DrawStringAnchored("سلام", S/2, S/2, 0.5, 0.5)

    dc.DrawRoundedRectangle(0, 0, 512, 512, 0)
    dc.DrawImage(im, 0, 0)
    dc.DrawStringAnchored("سلام", S/2, S/2, 0.5, 0.5)
    dc.Clip()
    dc.SavePNG("out.png")
}

output :
out

Question: How to draw multi image with clip or scale on context?

Firstly, thank you for the great work, it is helpful on drawing with Golang!

Code

package main

import (
	"log"

	"github.com/fogleman/gg"
)

func main() {
	im, err := gg.LoadImage("examples/lenna.png")
	if err != nil {
		log.Fatal(err)
	}

	dc := gg.NewContext(1024, 1024)
	dc.DrawRoundedRectangle(0, 0, 512, 512, 64)
	dc.Clip()
	dc.DrawImage(im, 0, 0)
	dc.DrawRoundedRectangle(512, 512, 512, 512, 64)
	dc.Clip()
	dc.DrawImage(im, 512, 512)
	dc.SavePNG("out.png")
}

Image

image

Wish

image

Best Wishes,
CosPotato

How to draw on RGB channels independently?

Hi! Is there a way to draw on each of an image's RGB channels independently? I need this for a game I'm developing.

Alternatively, is there a way to add (in the Porter-Duff sense) 3 single-channel images together?

FSavePNG(io.Writer, image.Image) variant

I wanted to ask if adding an FSavePNG function would be something that you'd consider. The reason for this is, I can connect your package to a web server or for usage where I wouldn't like to write to disk and easily connect it to other usages since it will take an io.Writer.
Also this means that we can also reuse FSavePNG in SavePNG in such a fashion.

func SavePNG(path string, img image.Image) error {
    f, err := os.Create(path)
    if err != nil {
      return err
    }
   defer f.Close()
   return FSavePNG(f, img)
}

func FSavePNG(w io.Writer, img image.Image) error {
    return png.Encode(w, img)
}

If this is something you'd consider, please let me know and I can create a PR for it.
Thank you.

Context.Pop() does not restore to previous state

When applying a clipping mask after saving the current context state, calling context.Pop() does not revert to the previous clipping mask. (It appears that this does not revert anything, but the effect on the mask is more obvious than other side effects.) Objects drawn after the call to Pop() are still affected by the mask.

Demonstration of issue. PR on the way.

params of DrawStringWrapped() ax, ay means ambiguous

It's says:

The anchor point is x - w * ax, y - h * ay, where w, h is the size of the
// text. Use ax=0.5, ay=0.5 to center the text at the specified point.

I'm not sure how to understanding the "anchor point", Does it the very central point ( both center of horizon and vertical ) of text area( or whole image?) ? Or the left top point of text area as OpenCV?

I noticed ax, ay coordinate with Align setting, but still cannt get it.

emoji text not drawn. Is there an option for supporting emojis?

When I modify a snippet text.go in examples/ ie

package main

import "github.com/fogleman/gg"

func main() {
    const S = 1024
    dc := gg.NewContext(S, S)
    dc.SetRGB(1, 1, 1)
    dc.Clear()
    dc.SetRGB(0, 0, 0)
    if err := dc.LoadFontFace("/Library/Fonts/Arial.ttf", 96); err != nil {
        panic(err)
    }
    dc.DrawStringAnchored("😎  🔥  🙏🏾 ", S/2, S/2, 0.5, 0.5)
    dc.SavePNG("out.png")
}

I get an image
out
and the emojis don't appear.
I wanted to ask if we have emoji support and if you might have any clues for how we could go around this.
Thank you.

Bad MeasureString for multiline strings

When I split line with newline symbol: It doesn't add in height, but increase width.

func test() {
	font := LoadFont()
	fontFace := truetype.NewFace(font, &truetype.Options{
		Size: 20,
	})

	ggContext := gg.NewContext(1000, 1000)

	ggContext.SetFontFace(fontFace)
	text1 := "asd asd"
	text2 := "asd\nasd"
	w1, h1 := ggContext.MeasureString(text1)
	w2, h2 := ggContext.MeasureString(text2)
	fmt.Printf("W1: %v, H1: %v\n", w1, h1)
	fmt.Printf("W2: %v, H2: %v\n", w2, h2)
}

I have output:

W1: 50, H1: 20
W2: 58, H2: 20

Tag commits

Hi,

Would you be able to tag your commits in master? It will give me peace of mind when releasing my project to prod.

Thanks :)

Question / Is is possible to draw a rounded image from a rectangle one ?

Hello,

Just wanted to know if there is a way I can draw a rounded rectangle image (from existing image rectangle image)?

I tried couple times but without any results, I am probably missing something.

What I tried :

  • Draw a rounded rectangle
  • Apply Fill()
  • Draw the image on top

Example :
I have a 300x150 raw image. I want to draw it in a context so it will become a rounded image (with a given radius) of the same size 300x150.

Is there any way of doing so ?

Thanks a lot.
Ben

Gradients containing translucent colors appear washed out

When rendering a gradient with semi-transparent colors, the output appears more "washed out" the lower the color alpha is. I have created a demonstration of this issue. The gradient on the left side of each image uses fully opaque colors; these appear unaffected. The gradient on the right side of each image uses the same colors at 50% alpha.

Fortunately the fix looks to be simple. colorLerp in gradient.go interpolates based on the alpha-premultiplied color values, but it returns a non-alpha-premultiplied color. Changing this line to return a color.RGBA struct appears to fix the problem. I will submit a PR to this effect.

draw polygon with different border and fill colors

Hi!

Awesome library, it's a joy to use!

I just want to make sure there isn't another way of creating a polygon (e.g. a circle)
which has its border of a given color and its filling of a different color.

My current approach is to draw 2 circles, the smaller one after the bigger one.

Cheers

Line width fine-control

I am trying to create the bimaps, and looks like I can't have vertical or horizontal line of width of exactly 1 px. Is there any way of making the width "strict"?

Subtract alpha from underlying shape

I am creating an image and filling it with black by drawing a rectangle to the context. I then want to draw circles in alpha on top of the image so that there are hole punches in it. Drawing circles to the context in alpha will just make invisible circles on to of the black rectangle, leaving me with a full black image. How do I make the drawing of the circles subtract colour from the rectangle?

Otherwise, perhaps there is a different method to obtain an image like the following one where the white should be transparent.
image

Can not open OpenSans

I download Open-Sans font from Google and start draw text but receive error:

panic: freetype: invalid TrueType format: bad kern table length

Could you explain me what happend and whats wrong I doing?

Question - is it possible to use gradients in text?

Say I wanted to simulate really really bad word art - like old school Microsoft Word memes. I've tried to do something like this:

grad := gg.NewLinearGradient(0, 72, 0, 72)
grad.AddColorStop(0, color.RGBA{63, 191, 63, 255})
grad.AddColorStop(1, color.RGBA{248, 43, 16, 255})

c.SetStrokeStyle(grad)
c.LoadFontFace("Impact.ttf", 72)
c.DrawStringAnchored(fmt.Sprintf("Friendship ended with %s", oldFriend), float64(500), float64(50), 0.5, 0.5)
c.Stroke()

TestPushPop fails with future Go 1.12

When running go test with the future Go 1.12 release, TestPushPop fails:

> go test
--- FAIL: TestPushPop (0.00s)
    context_test.go:26: expected hash: e0d6724eb72033577811a55f7a642f6a != actual hash: 31e908ee1c2ea180da98fd5681a89d05
FAIL
exit status 1
FAIL	github.com/fogleman/gg	0.042s

This appears to be due to https://golang.org/cl/153059, which changes the exact bit results returned by some trigonometric math functions. TestPushPop appears to be a change-detector test (https://testing.googleblog.com/2015/01/testing-on-toilet-change-detector-tests.html) in that it basically tests that some floating point operations return bit-for-bit identical results.

Text drawn with DrawStringWrapped appears in discrete characters for Arabic

When writing a text in arabic the characters are connected as follows :

عبد الفتاح السيسي

When I tried to use DrawStringWrapped it drawn the text in a descrete way, every character is not connected as follows:
image

The code snippet that generated the text in that image is as follows:

func drawName(dc *gg.Context, name string) {
	const height = 250
	dc.SetRGB(0, 0, 0)
	dc.DrawRectangle(0, HEIGHT-height, WIDTH, height)
	dc.Fill()

	if err := dc.LoadFontFace("font.ttf", 70); err != nil {
		return
	}
	dc.SetRGB(1, 1, 1)
	dc.DrawStringWrapped(name, 100, HEIGHT-height+70, 0, 0, WIDTH-200, 1.5, gg.AlignLeft)
	dc.Fill()
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.