Skip to content

Commit c8b819e

Browse files
committed
optimize: new unsafe syntax
1 parent e7201d6 commit c8b819e

5 files changed

Lines changed: 33 additions & 40 deletions

File tree

color.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ var (
2626
Opaque = color.RGBA{0, 0, 0, 0}
2727
)
2828

29-
// takecolor 实现基于k-means算法的图像取色算法
30-
func takecolor(img image.Image, k int) []color.RGBA {
31-
rgbaimg := imageToRGBA(img)
29+
// takeThemeColorsKMeans 实现基于k-means算法的图像取色算法
30+
func takeThemeColorsKMeans(img image.Image, k int) []color.RGBA {
31+
rgbaimg := ImageToRGBA(img)
3232
pixels := unsafe.Slice(
3333
(*color.RGBA)(unsafe.Pointer(unsafe.SliceData(rgbaimg.Pix))),
3434
uintptr(len(rgbaimg.Pix))/unsafe.Sizeof(color.RGBA{}),

color_test.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ func TestClustersEqual_DiffersOnlyInAlpha(t *testing.T) {
216216
func TestTakecolor_ReturnsKColors(t *testing.T) {
217217
img := solidImage(10, 10, color.RGBA{128, 64, 32, 255})
218218
for k := 1; k <= 5; k++ {
219-
result := takecolor(img, k)
219+
result := takeThemeColorsKMeans(img, k)
220220
if len(result) != k {
221221
t.Errorf("takecolor with k=%d returned %d colors, want %d", k, len(result), k)
222222
}
@@ -226,7 +226,7 @@ func TestTakecolor_ReturnsKColors(t *testing.T) {
226226
func TestTakecolor_SolidColorK1(t *testing.T) {
227227
c := color.RGBA{200, 100, 50, 255}
228228
img := solidImage(20, 20, c)
229-
result := takecolor(img, 1)
229+
result := takeThemeColorsKMeans(img, 1)
230230
if len(result) != 1 {
231231
t.Fatalf("expected 1 color, got %d", len(result))
232232
}
@@ -242,7 +242,7 @@ func TestTakecolor_SolidColorKGreaterThan1(t *testing.T) {
242242
// 故只验证:返回 k 个颜色,且其中至少一个与原始颜色完全匹配。
243243
c := color.RGBA{10, 200, 150, 255}
244244
img := solidImage(15, 15, c)
245-
result := takecolor(img, 3)
245+
result := takeThemeColorsKMeans(img, 3)
246246
if len(result) != 3 {
247247
t.Fatalf("expected 3 colors, got %d", len(result))
248248
}
@@ -264,7 +264,7 @@ func TestTakecolor_TwoDistinctColors(t *testing.T) {
264264
img := twoColorImage(20, 20, Red, Blue)
265265
const maxAttempts = 30
266266
for range maxAttempts {
267-
result := takecolor(img, 2)
267+
result := takeThemeColorsKMeans(img, 2)
268268
if len(result) == 2 && colorInSlice(Red, result, 5) && colorInSlice(Blue, result, 5) {
269269
return // 成功分离,测试通过
270270
}
@@ -276,8 +276,8 @@ func TestTakecolor_Deterministic_SolidImage(t *testing.T) {
276276
// 纯色图像下,无论随机种子如何,结果应完全一致
277277
c := color.RGBA{77, 88, 99, 255}
278278
img := solidImage(10, 10, c)
279-
r1 := takecolor(img, 2)
280-
r2 := takecolor(img, 2)
279+
r1 := takeThemeColorsKMeans(img, 2)
280+
r2 := takeThemeColorsKMeans(img, 2)
281281
if !clustersEqual(r1, r2) {
282282
t.Errorf("takecolor on solid image should be deterministic: r1=%v, r2=%v", r1, r2)
283283
}
@@ -296,7 +296,7 @@ func TestTakecolor_AllClustersHaveValidRGB(t *testing.T) {
296296
})
297297
}
298298
}
299-
result := takecolor(img, 4)
299+
result := takeThemeColorsKMeans(img, 4)
300300
if len(result) != 4 {
301301
t.Fatalf("expected 4 clusters, got %d", len(result))
302302
}
@@ -352,7 +352,7 @@ func BenchmarkTakecolor_16x16_K3(b *testing.B) {
352352
}
353353
b.ResetTimer()
354354
for range b.N {
355-
takecolor(img, 3)
355+
takeThemeColorsKMeans(img, 3)
356356
}
357357
}
358358

@@ -366,7 +366,7 @@ func BenchmarkTakecolor_64x64_K4(b *testing.B) {
366366
}
367367
b.ResetTimer()
368368
for range b.N {
369-
takecolor(img, 4)
369+
takeThemeColorsKMeans(img, 4)
370370
}
371371
}
372372

@@ -380,14 +380,14 @@ func BenchmarkTakecolor_128x128_K8(b *testing.B) {
380380
}
381381
b.ResetTimer()
382382
for range b.N {
383-
takecolor(img, 8)
383+
takeThemeColorsKMeans(img, 8)
384384
}
385385
}
386386

387387
func BenchmarkTakecolor_SolidColor_K5(b *testing.B) {
388388
img := solidImage(64, 64, color.RGBA{200, 100, 50, 255})
389389
b.ResetTimer()
390390
for range b.N {
391-
takecolor(img, 5)
391+
takeThemeColorsKMeans(img, 5)
392392
}
393393
}

context.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func NewContext(width, height int) *Context {
129129
// 将指定图像复制到一个新的 image.RGBA
130130
// 并准备渲染到该图像上的上下文。
131131
func NewContextForImage(im image.Image) *Context {
132-
return NewContextForRGBA(imageToRGBA(im))
132+
return NewContextForRGBA(ImageToRGBA(im))
133133
}
134134

135135
// NewContextForRGBA prepares a context for rendering onto the specified image.
@@ -820,12 +820,10 @@ func (dc *Context) InvertMask() {
820820
if dc.mask == nil {
821821
dc.mask = image.NewAlpha(dc.im.Bounds())
822822
} else {
823-
var u64s []uint64
824-
raws := (*slice)(unsafe.Pointer(&dc.mask.Pix))
825-
rawu64s := (*slice)(unsafe.Pointer(&u64s))
826-
rawu64s.data = raws.data
827-
rawu64s.len = raws.len / 8
828-
rawu64s.cap = raws.cap / 8
823+
u64s := unsafe.Slice((*uint64)(
824+
unsafe.Pointer(unsafe.SliceData(dc.mask.Pix))),
825+
len(dc.mask.Pix)/8,
826+
)
829827
for i, v := range u64s {
830828
u64s[i] = 0xffffffff_ffffffff - v
831829
}
@@ -1364,9 +1362,9 @@ func (dc *Context) String() string {
13641362
return sb.String()
13651363
}
13661364

1367-
// TakeColor extracts the k dominant colors from the drawn image using k-means.
1365+
// TakeThemeColorsKMeans extracts the k dominant colors from the drawn image using k-means.
13681366
//
1369-
// TakeColor 使用 k-means 算法从已绘制图像中提取 k 个主色。
1370-
func (dc *Context) TakeColor(k int) []color.RGBA {
1371-
return takecolor(dc.im, k)
1367+
// TakeThemeColorsKMeans 使用 k-means 算法从已绘制图像中提取 k 个主色。
1368+
func (dc *Context) TakeThemeColorsKMeans(k int) []color.RGBA {
1369+
return takeThemeColorsKMeans(dc.im, k)
13721370
}

path.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
)
99

1010
func flattenPath(p raster.Path) [][]Point {
11-
var result [][]Point
12-
var path []Point
11+
var result = make([][]Point, len(p)*2)
12+
var path = make([]Point, 0, len(p)*2)
1313
var cx, cy float64
1414
for i := 0; i < len(p); {
1515
switch p[i] {
@@ -64,13 +64,13 @@ func flattenPath(p raster.Path) [][]Point {
6464
}
6565

6666
func dashPath(paths [][]Point, dashes []float64, offset float64) [][]Point {
67-
var result [][]Point
6867
if len(dashes) == 0 {
6968
return paths
7069
}
7170
if len(dashes) == 1 {
7271
dashes = append(dashes, dashes[0])
7372
}
73+
var result = make([][]Point, 0, len(paths)*2)
7474
for _, path := range paths {
7575
if len(path) < 2 {
7676
continue
@@ -100,7 +100,7 @@ func dashPath(paths [][]Point, dashes []float64, offset float64) [][]Point {
100100
}
101101
}
102102

103-
var segment []Point
103+
var segment = make([]Point, 0, (len(path)-pathIndex)*2)
104104
segment = append(segment, previous)
105105
for pathIndex < len(path) {
106106
dashLength := dashes[dashIndex]
@@ -114,7 +114,7 @@ func dashPath(paths [][]Point, dashes []float64, offset float64) [][]Point {
114114
if dashIndex%2 == 0 && len(segment) > 1 {
115115
result = append(result, segment)
116116
}
117-
segment = make([]Point, 0, 1)
117+
segment = make([]Point, 0, (len(path)-pathIndex)*2)
118118
segment = append(segment, p)
119119
segmentLength = 0
120120
previous = p
@@ -134,7 +134,7 @@ func dashPath(paths [][]Point, dashes []float64, offset float64) [][]Point {
134134
}
135135

136136
func rasterPath(paths [][]Point) raster.Path {
137-
var result raster.Path
137+
var result = make(raster.Path, 0, len(paths))
138138
for _, path := range paths {
139139
var previous fixed.Point26_6
140140
for i, point := range path {

util.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@ func Degrees(radians float64) float64 {
3434
//
3535
// ImageToRGBA 将 image.Image 转换为 *image.RGBA。
3636
func ImageToRGBA(src image.Image) *image.RGBA {
37-
return imageToRGBA(src)
38-
}
39-
40-
// image.Image 转为 image.RGBA
41-
func imageToRGBA(src image.Image) *image.RGBA {
4237
bounds := src.Bounds()
4338
dst := image.NewRGBA(bounds)
4439
draw.Draw(dst, bounds, src, bounds.Min, draw.Src)
@@ -186,9 +181,9 @@ func ParseFontFace(b []byte, points float64) (face font.Face, err error) {
186181
return
187182
}
188183

189-
// TakeColor extracts the k dominant colors from an image using k-means.
184+
// TakeThemeColorsKMeans extracts the k dominant colors from an image using k-means.
190185
//
191-
// TakeColor 使用 k-means 算法从图像中提取 k 个主色。
192-
func TakeColor(img image.Image, k int) []color.RGBA {
193-
return takecolor(img, k)
186+
// TakeThemeColorsKMeans 使用 k-means 算法从图像中提取 k 个主色。
187+
func TakeThemeColorsKMeans(img image.Image, k int) []color.RGBA {
188+
return takeThemeColorsKMeans(img, k)
194189
}

0 commit comments

Comments
 (0)