-
Notifications
You must be signed in to change notification settings - Fork 0
/
transcolor.go
47 lines (39 loc) · 1.33 KB
/
transcolor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package transcolor
import (
"image"
"image/color"
"github.com/lucasb-eyer/go-colorful"
)
// Transfer transfers color palette from one image to other
// It adjust color of source image based on target image
func Transfer(src, target image.Image) image.Image {
srcLab := ImageToLab(src)
targetLab := ImageToLab(target)
srcLabStat := srcLab.Stat()
targetLabStat := targetLab.Stat()
forEachLABCounter(targetLab, func(l, a, b float64, counter int) {
targetLab.Pix[counter] = calculateNewPix(l, targetLabStat.LStat, srcLabStat.LStat)
targetLab.Pix[counter+1] = calculateNewPix(a, targetLabStat.AStat, srcLabStat.AStat)
targetLab.Pix[counter+2] = calculateNewPix(b, targetLabStat.BStat, srcLabStat.BStat)
})
newTargetRGBA := image.NewRGBA(target.Bounds())
ind := 0
for x := target.Bounds().Min.X; x < target.Bounds().Max.X; x++ {
for y := target.Bounds().Min.Y; y < target.Bounds().Max.Y; y++ {
_, _, _, A := target.At(x, y).RGBA()
c := colorful.Lab(targetLab.Pix[ind], targetLab.Pix[ind+1], targetLab.Pix[ind+2])
R, G, B := c.Clamped().RGB255()
newTargetRGBA.Set(x, y, color.NRGBA{
R: R,
G: G,
B: B,
A: uint8(A>>8),
})
ind += 3
}
}
return newTargetRGBA
}
func calculateNewPix(src float64, targetStat, srcStat Stat) float64 {
return (src-targetStat.Mean)*(srcStat.StdDev/targetStat.StdDev) + srcStat.Mean
}