mirror of
https://github.com/IllusionMan1212/ColorX.git
synced 2026-10-24 02:12:32 +00:00
feat: implement main logic and implement webp support
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
# ColorX (WIP)
|
||||
# ColorX
|
||||
ColorX is a library to determine the most prominent color in an image.
|
||||
ColorX doesn't use any sort of complex algorithms to calculate the prominent color, it simply loops over the image pixels and returns the color that occurs the most.
|
||||
|
||||
The `getProminentColor` function returns the color in 2 formats, a hex string such as: `#abfecd` and a variable of type `color.Color`.
|
||||
|
||||
# Example
|
||||
Example code is written in [example/example.go](https://github.com/illusionman1212/colorx/blob/master/example/example.go)
|
||||
An example on how to use this library is written in [example/example.go](https://github.com/illusionman1212/colorx/blob/master/example/example.go)
|
||||
|
||||
# Supported Image Formats
|
||||
Currently ColorX supports these image formats:
|
||||
- png
|
||||
- jpeg
|
||||
- webp
|
||||
|
||||
@@ -20,28 +20,91 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"strconv"
|
||||
|
||||
"image/color"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
|
||||
_ "golang.org/x/image/webp"
|
||||
)
|
||||
|
||||
// downsampleImage downsamples images larger than 20000px for faster image processing.
|
||||
func downsampleImage(img image.Image) image.Image {
|
||||
// TODO: implement downsampling
|
||||
return img
|
||||
}
|
||||
|
||||
// calculateColorMap loops through the image pixels and creates a map-
|
||||
// of all unique pixel colors and how many times they occur.
|
||||
func calculateColorMap(img image.Image, width int, height int) map[color.Color]int {
|
||||
colorMap := map[color.Color]int{}
|
||||
|
||||
for x := 0; x < width; x++ {
|
||||
for y := 0; y < height; y++ {
|
||||
color := img.At(x, y)
|
||||
// if the alpha is bigger than 100 then add the color to the map
|
||||
if _, _, _, a := color.RGBA(); a > 100 {
|
||||
colorMap[color] = colorMap[color] + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return colorMap
|
||||
}
|
||||
|
||||
// GetProminentColor gets the most prominent color in the image bytes reader that gets passed in.
|
||||
// returns a hex color as a string.
|
||||
func GetProminentColor(data []byte) (string, error) {
|
||||
func GetProminentColor(data []byte) (string, color.Color, error) {
|
||||
buf := bytes.NewBuffer(data)
|
||||
img, _, err := image.Decode(buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
width := img.Bounds().Max.X
|
||||
height := img.Bounds().Max.Y
|
||||
|
||||
// amount of pixels in image
|
||||
pixels := height * width
|
||||
|
||||
fmt.Printf("Pixels in image: %v\n", pixels)
|
||||
fmt.Printf("Width: %v\n", width)
|
||||
fmt.Printf("Height: %v\n", height)
|
||||
|
||||
return "", nil
|
||||
// image is too big, downsample to a reasonable size
|
||||
if pixels > 20000 {
|
||||
img = downsampleImage(img)
|
||||
}
|
||||
|
||||
colorMap := calculateColorMap(img, width, height)
|
||||
|
||||
var maxColor color.Color
|
||||
maxAmmount := 0
|
||||
|
||||
for color, amount := range colorMap {
|
||||
if amount > maxAmmount {
|
||||
maxColor = color
|
||||
maxAmmount = amount
|
||||
}
|
||||
}
|
||||
|
||||
RGBAColor := color.RGBAModel.Convert(maxColor).(color.RGBA)
|
||||
|
||||
red := strconv.FormatUint(uint64(RGBAColor.R), 16)
|
||||
green := strconv.FormatUint(uint64(RGBAColor.G), 16)
|
||||
blue := strconv.FormatUint(uint64(RGBAColor.B), 16)
|
||||
|
||||
// prepend 0 if the hex number has less than 2 digits
|
||||
if len(red) < 2 {
|
||||
red = "0" + red
|
||||
}
|
||||
|
||||
if len(green) < 2 {
|
||||
green = "0" + green
|
||||
}
|
||||
|
||||
if len(blue) < 2 {
|
||||
blue = "0" + blue
|
||||
}
|
||||
|
||||
hexColor := fmt.Sprintf("#%2s%2s%2s", red, green, blue)
|
||||
|
||||
return hexColor, maxColor, nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ func main() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
color, err := colorx.GetProminentColor(data)
|
||||
color, _, err := colorx.GetProminentColor(data)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
module github.com/illusionman1212/colorx
|
||||
|
||||
go 1.16
|
||||
|
||||
require golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
Reference in New Issue
Block a user