Convert Figma logo to code with AI

esimov logotriangle

Convert images to computer generated art using delaunay triangulation.

2,037
109
2,037
2

Top Related Projects

12,644

Reproducing images with geometric primitives.

1,479

Cairo in Go: vector to raster, SVG, PDF, EPS, WASM, OpenGL, Gio, etc.

4,448

A hand-crafted 2D game library in Go

10,770

Ebitengine - A dead simple 2D game engine for Go

1,541

A pure Go game engine

Quick Overview

Triangle is an image processing library written in Go that converts images into artistic triangular polygons. It uses the Delaunay triangulation algorithm to generate a mesh of triangles from the image's significant points, then fills these triangles with the average color of the area they cover in the original image.

Pros

  • Produces unique, artistic renderings of images
  • Highly customizable with various parameters for fine-tuning results
  • Supports both image files and webcam input
  • Includes a command-line interface for easy use

Cons

  • Processing large images or using a high number of points can be computationally intensive
  • The quality of the output heavily depends on the input image and chosen parameters
  • Limited documentation for advanced usage and customization
  • May not preserve fine details in complex images

Code Examples

  1. Basic image processing:
package main

import (
    "github.com/esimov/triangle"
    "image"
    _ "image/jpeg"
    "os"
)

func main() {
    file, _ := os.Open("input.jpg")
    img, _, _ := image.Decode(file)
    
    processor := triangle.NewProcessor()
    output, _ := processor.Process(img)
    
    outputFile, _ := os.Create("output.png")
    triangle.SavePNG(outputFile, output)
}
  1. Customizing triangulation parameters:
processor := triangle.NewProcessor()
processor.BlurRadius = 4
processor.SobelThreshold = 10
processor.PointsThreshold = 20
processor.MaxPoints = 2500
processor.Wireframe = true
  1. Processing webcam input:
webcam, _ := triangle.NewWebcam()
processor := triangle.NewProcessor()

for {
    src, _ := webcam.Read()
    output, _ := processor.Process(src)
    // Display or save the output
}

Getting Started

  1. Install the library:

    go get -u github.com/esimov/triangle
    
  2. Import the library in your Go code:

    import "github.com/esimov/triangle"
    
  3. Create a new processor and process an image:

    processor := triangle.NewProcessor()
    output, err := processor.Process(inputImage)
    if err != nil {
        // Handle error
    }
    // Use the output image
    
  4. Alternatively, use the command-line interface:

    triangle -in input.jpg -out output.png -points 2500 -blur 2
    

Competitor Comparisons

12,644

Reproducing images with geometric primitives.

Pros of Primitive

  • Supports multiple output formats (SVG, PNG, GIF)
  • Offers more shape options (triangles, rectangles, ellipses, etc.)
  • Provides CLI and library interfaces for flexibility

Cons of Primitive

  • Written in Go, which may have a steeper learning curve for some developers
  • Slower processing time compared to Triangle
  • Requires more system resources for complex images

Code Comparison

Triangle (Go):

triangles := primitive.Triangles(img, 100)
for _, t := range triangles {
    draw.DrawTriangle(dst, t, t.Color, draw.Over)
}

Primitive (Go):

model := primitive.NewModel(input.Image())
for i := 0; i < 100; i++ {
    model.Step(primitive.ShapeTypeTriangle)
}
output := model.Image()

Key Differences

  • Triangle focuses solely on triangles, while Primitive offers multiple shape options
  • Triangle is optimized for speed and efficiency, while Primitive prioritizes versatility
  • Primitive provides more control over the output format and appearance
  • Triangle's implementation is simpler and more straightforward
  • Primitive offers a more comprehensive set of features for image manipulation

Both projects aim to create artistic renderings of images using geometric shapes, but they cater to different use cases and preferences. Triangle is ideal for quick, triangle-based transformations, while Primitive offers more flexibility and output options at the cost of increased complexity and processing time.

1,479

Cairo in Go: vector to raster, SVG, PDF, EPS, WASM, OpenGL, Gio, etc.

Pros of Canvas

  • More comprehensive graphics library with support for various shapes, paths, and text rendering
  • Offers both vector and raster output formats (SVG, PDF, PNG)
  • Actively maintained with regular updates and improvements

Cons of Canvas

  • Larger codebase and potentially steeper learning curve
  • May be overkill for simple triangulation tasks
  • Slower performance for specific triangle-based operations

Code Comparison

Triangle (image triangulation):

triangles, _ := triangle.Process(srcImage, 300, 50)
triangle.Draw(triangles, 800, 600, func() {})

Canvas (drawing triangles):

ctx := canvas.New(800, 600)
ctx.MoveTo(0, 0)
ctx.LineTo(400, 600)
ctx.LineTo(800, 0)
ctx.FillStroke()

Summary

Triangle focuses specifically on image triangulation and provides a simpler API for this task. Canvas is a more versatile graphics library that can handle various drawing operations, including triangles. While Canvas offers more features, Triangle may be more suitable for projects that primarily require image triangulation. The choice between the two depends on the specific requirements of your project and the desired level of control over graphics operations.

4,448

A hand-crafted 2D game library in Go

Pros of Pixel

  • More comprehensive 2D game development framework with features like sprite handling, audio support, and input management
  • Active development with regular updates and a larger community
  • Extensive documentation and examples for easier learning and implementation

Cons of Pixel

  • Larger and more complex codebase, which may be overkill for simple graphics tasks
  • Steeper learning curve for beginners due to its broader feature set
  • Potentially higher resource usage compared to Triangle's focused approach

Code Comparison

Triangle (image processing):

triangulated := triangle.Process(src, dst, triangles, blur, noise, strokeWidth)

Pixel (drawing a triangle):

imd := imdraw.New(nil)
imd.Push(pixel.V(100, 100), pixel.V(200, 200), pixel.V(300, 100))
imd.Polygon(0)
imd.Draw(win)

Summary

Triangle is a specialized library for image processing and triangulation, while Pixel is a more comprehensive 2D game development framework. Triangle excels in its specific use case of creating triangulated images, offering a simpler API for this task. Pixel, on the other hand, provides a wider range of features for game development, including graphics, input handling, and audio support. The choice between the two depends on the project requirements: Triangle for focused image triangulation, or Pixel for broader 2D game development needs.

10,770

Ebitengine - A dead simple 2D game engine for Go

Pros of Ebiten

  • More comprehensive game development framework with broader capabilities
  • Extensive documentation and examples for easier learning
  • Cross-platform support for multiple operating systems and devices

Cons of Ebiten

  • Steeper learning curve due to its more extensive feature set
  • Potentially overkill for simple graphics or image processing tasks
  • Larger codebase and dependencies compared to Triangle

Code Comparison

Triangle (image processing):

triangulated := triangle.NewTriangulator(image)
triangles, _ := triangulated.Process()

Ebiten (game development):

type Game struct{}

func (g *Game) Update() error {
    // Update game logic
    return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
    // Draw game elements
}

Summary

Triangle is focused on image processing and triangulation, making it simpler for specific tasks. Ebiten is a full-fledged game development framework with broader capabilities but may be more complex for basic image manipulation. Choose Triangle for lightweight image processing or Ebiten for comprehensive game development needs.

1,541

A pure Go game engine

Pros of Oak

  • More comprehensive game development framework with features like collision detection, event handling, and scene management
  • Active development with regular updates and a growing community
  • Extensive documentation and examples for easier learning and implementation

Cons of Oak

  • Steeper learning curve due to its broader scope and more complex architecture
  • Potentially overkill for simple graphics or image processing tasks
  • Larger codebase and dependencies, which may increase project size

Code Comparison

Triangle (image processing):

triangulated := triangle.Process(img, 500, 50)

Oak (game development):

oak.Add("scene",
    func(string, interface{}) {
        oak.Draw(player)
        oak.Draw(enemy)
    },
    func() bool {
        return player.Collides(enemy)
    },
)

Summary

Triangle focuses on image processing and triangulation, making it ideal for specific graphical effects. Oak, on the other hand, is a full-fledged game development framework with a wider range of features. While Oak offers more comprehensive tools for creating games, it may be excessive for simple image manipulation tasks. Triangle is more lightweight and easier to integrate for basic image processing, but lacks the extensive game development capabilities of Oak.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Triangle logo

build Go Report Card Go Reference license release homebrew

▲ Triangle is a tool for generating triangulated image using delaunay triangulation. It takes a source image and converts it to an abstract image composed of tiles of triangles.

Sample image

The process

  • First the image is blured out to smoth out the sharp pixel edges. The more blured an image is the more diffused the generated output will be.
  • Second the resulted image is converted to grayscale mode.
  • Then a sobel filter operator is applied on the grayscaled image to obtain the image edges. An optional threshold value is applied to filter out the representative pixels of the resulted image.
  • A convolution filter operator is applied over the image data in order to adjust its final aspect prior running the delaunay triangulation process.
  • Lastly the delaunay algorithm is applied on the pixels obtained from the previous step.

Features

  • Can process recursively whole directories and subdirectories concurrently.
  • Supports various image types.
  • There is no need to specify the file type, the CLI tool can recognize automatically the input and output file type.
  • Can accept image URL as parameter for the -in flag.
  • Possibility to save the generated image as an SVG file.
  • The generated SVG file can be accessed from the Web browser directly.
  • Clean and intuitive API. The API not only that accepts image files but can also work with image data. This means that the Draw method can be invoked even on data streams. Check this demo for reference.
  • Support for pipe names (possibility to pipe in and pipe out the source and destination image).

TODO

  • Standalone and native GUI application

Head over to this subtopic to get a better understanding of the supported features.

Installation and usage

$ go install github.com/esimov/triangle/v2/cmd/triangle@v2.0.0 

You can also download the binary file from the releases folder.

MacOS (Brew) install

The library can be installed via Homebrew too.

$ brew install triangle

API usage

proc := &triangle.Processor{
	MaxPoints:  2500,
	BlurRadius: 2,
	PointRate:  0.75,
	BlurFactor: 1,
	EdgeFactor: 6,
}

img := &triangle.Image{
	Processor: *proc,
}

input, err := os.Open("input.jpg")
if err != nil {
	log.Fatalf("error opening the source file: %v", err)
}

// decode image
src, err := img.DecodeImage(input)
if err != nil {
	log.Fatalf("error decoding the image: %v", err)
}
res, _, _, err := img.Draw(src, *proc, func() {})
if err != nil {
	log.Fatalf("error generating the triangles: %v", err)
}

output, err := os.Create("output.png")
if err != nil {
	log.Fatalf("error opening the destination file: %v", err)
}

// encode image
png.Encode(output, res)

Supported commands

$ triangle --help

The following flags are supported:

FlagDefaultDescription
inn/aSource image
outn/aDestination image
bl2Blur radius
nf0Noise factor
bf1Blur factor
ef6Edge factor
pr0.075Point rate
pth10Points threshold
pts2500Maximum number of points
so10Sobel filter threshold
slfalseUse solid stroke color (yes/no)
wf0Wireframe mode (0: without stroke, 1: with stroke, 2: stroke only)
st1Stroke width
grfalseOutput in grayscale mode
webfalseOpen the SVG file in the web browser
bg' 'Background color (specified as hex value)
cwsystem spec.Number of files to process concurrently

Key features

Process multiple images from a directory concurrently

The CLI tool also let you process multiple images from a directory concurrently. You only need to provide the source and the destination folder by using the -in and -out flags.

$ triangle -in <input_folder> -out <output-folder>

You can provide also an image file URL for the -in flag.

$ triangle -in <image_url> -out <output-folder>

Pipe names

The CLI tool accepts also pipe names, which means you can use stdin and stdout without the need of providing a value for the -in and -out flag directly since these defaults to -. For this reason it's possible to use curl for example for downloading an image from the internet and invoke the triangulation process over it directly without the need of getting the image first and calling ▲ Triangle afterwards.

Here are some examples using pipe names:

$ curl -s <image_url> | triangle > out.jpg
$ cat input/source.jpg | triangle > out.jpg
$ triangle -in input/source.jpg > out.jpg
$ cat input/source.jpg | triangle -out out.jpg
$ triangle -out out.jpg < input/source.jpg

Background color

You can specify a background color in case of transparent background images (.png) by using the -bg flag. This flag accepts a hexadecimal string value. For example setting the flag to -bg=#ffffff00 will set the alpha channel of the resulted image transparent.

Output as image or SVG

By default the output is saved to an image file, but you can export the resulted vertices even to an SVG file. The CLI tool can recognize the output type directly from the file extension. This is a handy addition for those who wish to generate large images without guality loss.

$ triangle -in samples/input.jpg -out output.svg

Using with -web flag you can access the generated svg file directly on the web browser.

$ triangle -in samples/input.jpg -out output.svg -web=true

Supported output types

The following output file types are supported: .jpg, .jpeg, .png, .bmp, .svg.

Tweaks

Setting a lower points threshold, the resulted image will be more like a cubic painting. You can even add a noise factor, generating a more artistic, grainy image.

Here are some examples you can experiment with:

$ triangle -in samples/input.jpg -out output.png -wf=0 -pts=3500 -st=2 -bl=2
$ triangle -in samples/input.jpg -out output.png -wf=2 -pts=5500 -st=1 -bl=10

Examples

Triangle1 Triangle2 Triangle3

License

Copyright © 2018 Endre Simo

This project is under the MIT License. See the LICENSE file for the full license text.