README
¶
Octree Color Quantizer
This project implements an octree-based color quantization algorithm in Go to reduce the number of colors in an image while preserving visual quality. The octree color quantizer helps create a palette of colors from an input image and then maps the colors in the image to this palette, which can be useful for tasks like image compression and color reduction.
Features
- Color Quantization: Reduces the number of colors in an image using an octree-based quantization algorithm.
- Palette Generation: Generates a color palette with a specified number of colors.
- Image Conversion: Converts an input image to use the generated palette.
- Palette Visualization: Creates and saves an image showing the generated color palette.
Code Overview
Usage
for running the code,
go run main.go # Uses defaults: input.png, depth=8, colors=256
go run main.go path/to/image.png # Process specific image with default settings
go run main.go path/to/image.gif # Process specific GIF with default settings
go run main.go path/to/image.png 4 # Process image with depth=4, colors=16
go run main.go path/to/image.png 6 50 # Process image with depth=6, colors=50
go run main.go 4 32 # Process default image with depth=4, colors=32
func forImages() {
// Load the image
file, err := os.Open("input.png")
if err != nil {
fmt.Println("Error opening image:", err)
return
}
defer file.Close()
img, err := png.Decode(file)
if err != nil {
fmt.Println("Error decoding image:", err)
return
}
// Create an OctreeQuantizer
quantizer := NewOctreeQuantizer()
// Add colors from the image to the quantizer
bounds := img.Bounds()
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
color := Color{
Red: int(r >> 8),
Green: int(g >> 8),
Blue: int(b >> 8),
Alpha: int(a >> 8),
}
quantizer.AddColor(color)
}
}
// Generate the color palette
colorCount := 256 // Number of colors in the palette
palette := quantizer.MakePalette(colorCount)
// Create a new image with the quantized colors
quantizedImg := image.NewRGBA(bounds)
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, a := img.At(x, y).RGBA()
color_palette := Color{
Red: int(r >> 8),
Green: int(g >> 8),
Blue: int(b >> 8),
Alpha: int(a >> 8),
}
paletteIndex := quantizer.GetPaletteIndex(color_palette)
quantizedColor := palette[paletteIndex]
quantizedImg.Set(x, y, color.RGBA{
R: uint8(quantizedColor.Red),
G: uint8(quantizedColor.Green),
B: uint8(quantizedColor.Blue),
A: uint8(quantizedColor.Alpha),
})
}
}
// Save the quantized image
outputFile, err := os.Create("output.png")
if err != nil {
fmt.Println("Error creating output image:", err)
return
}
defer outputFile.Close()
err = png.Encode(outputFile, quantizedImg)
if err != nil {
fmt.Println("Error encoding output image:", err)
return
}
fmt.Println("Quantized image saved as output.png")
// Create a palette image with larger pixels
pixelSize := 10
paletteImg := image.NewRGBA(image.Rect(0, 0, 8*pixelSize, ((colorCount+7)/8)*pixelSize))
for i, c := range palette {
x := (i % 8) * pixelSize
y := (i / 8) * pixelSize
for dx := 0; dx < pixelSize; dx++ {
for dy := 0; dy < pixelSize; dy++ {
paletteImg.Set(x+dx, y+dy, color.RGBA{
R: uint8(c.Red),
G: uint8(c.Green),
B: uint8(c.Blue),
A: uint8(c.Alpha),
})
}
}
}
// Save the palette image
paletteFile, err := os.Create("palette.png")
if err != nil {
fmt.Println("Error creating palette image:", err)
return
}
defer paletteFile.Close()
err = png.Encode(paletteFile, paletteImg)
if err != nil {
fmt.Println("Error encoding palette image:", err)
return
}
fmt.Println("Palette image saved as palette.png")
}
Key Components
Color: Represents a color with Red, Green, and Blue components.OctreeNode: Represents a node in the octree. Each node can have up to 8 children.OctreeQuantizer: Manages the octree and provides methods to add colors, generate palettes, and get color indices.
Functions
NewColor(red, green, blue int) Color: Creates a newColorinstance.NewOctreeNode(level int, parent *OctreeQuantizer) *OctreeNode: Creates a newOctreeNode.AddColor(color Color): Adds a color to the quantizer.MakePalette(colorCount int) []Color: Generates a color palette with the specified number of colors.GetPaletteIndex(color Color) int: Gets the index of the color in the palette.
Example
Original Image
The original image is located at examples/alice. It is 2.27MB in size.

Quantized Image
The quantized image is located at examples/quantized_alice. It is 0.51MB in size and contains 64 colors.

Quantized Palette
The palette used for the quantized image is located at examples/quantized_palette.

Contributing
Feel free to submit issues, pull requests, and suggestions to improve the project.
Documentation
¶
There is no documentation for this package.