156 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package drawhelper
import (
"image"
"image/color"
"git.lxtend.com/lixiangwuxian/imagedd/util"
)
// 辅助函数:在图像上绘制宽线条
func DrawThickLineOnImage(img *image.RGBA, x0, y0, x1, y1, width int, color color.Color) {
// 获取颜色分量
r, g, b, a := color.RGBA()
r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)
bounds := img.Bounds()
// 使用Bresenham算法绘制线段作为中心线
dx := util.Abs(x1 - x0)
dy := util.Abs(y1 - y0)
sx, sy := 1, 1
if x0 >= x1 {
sx = -1
}
if y0 >= y1 {
sy = -1
}
err := dx - dy
// 计算线宽的一半(向下取整)
halfWidth := width / 2
// 绘制线条
x, y := x0, y0
for {
// 绘制宽线条(在中心点周围绘制圆形区域)
for wy := -halfWidth; wy <= halfWidth; wy++ {
for wx := -halfWidth; wx <= halfWidth; wx++ {
// 只绘制在线宽范围内的点(圆形区域)
if wx*wx+wy*wy <= halfWidth*halfWidth {
DrawPointIfInBounds(img, bounds, x+wx, y+wy, r8, g8, b8, a8)
}
}
}
if x == x1 && y == y1 {
break
}
e2 := 2 * err
if e2 > -dy {
err -= dy
x += sx
}
if e2 < dx {
err += dx
y += sy
}
}
}
// 辅助函数:在图像上绘制线段
func DrawLineOnImage(img *image.RGBA, x0, y0, x1, y1 int, color color.Color) {
r, g, b, a := color.RGBA()
r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)
// 输出颜色值用于调试
// log.Printf("绘制线条: 颜色 RGBA(%d,%d,%d,%d)", r8, g8, b8, a8)
bounds := img.Bounds()
// 使用Bresenham算法绘制线段
dx := util.Abs(x1 - x0)
dy := util.Abs(y1 - y0)
sx, sy := 1, 1
if x0 >= x1 {
sx = -1
}
if y0 >= y1 {
sy = -1
}
err := dx - dy
for {
// 绘制点,但只在有效范围内
DrawPointIfInBounds(img, bounds, x0, y0, r8, g8, b8, a8)
if x0 == x1 && y0 == y1 {
break
}
e2 := 2 * err
if e2 > -dy {
err -= dy
x0 += sx
}
if e2 < dx {
err += dx
y0 += sy
}
}
}
// 辅助函数:在图像上绘制圆
func DrawCircleOnImage(img *image.RGBA, x0, y0 int, radius float64, color color.Color) {
r, g, b, a := color.RGBA()
r8, g8, b8, a8 := uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)
// 使用Bresenham算法绘制圆
x := float64(0)
y := float64(radius)
d := 3 - 2*radius
bounds := img.Bounds()
for {
// 绘制8个对称点但只在图像范围内
DrawPointIfInBounds(img, bounds, x0+int(x), y0+int(y), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0+int(x), y0-int(y), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0-int(x), y0+int(y), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0-int(x), y0-int(y), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0+int(y), y0+int(x), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0+int(y), y0-int(x), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0-int(y), y0+int(x), r8, g8, b8, a8)
DrawPointIfInBounds(img, bounds, x0-int(y), y0-int(x), r8, g8, b8, a8)
if d < 0 {
d += 4*x + 6
} else {
d += 4*(x-y) + 10
y--
}
x++
if x > y {
break
}
}
}
// 辅助函数:在图像上设置像素,但只在有效范围内
func DrawPointIfInBounds(img *image.RGBA, bounds image.Rectangle, x, y int, r, g, b, a uint8) {
if x >= bounds.Min.X && x < bounds.Max.X && y >= bounds.Min.Y && y < bounds.Max.Y {
// 记录绘制的像素位置和颜色,便于调试
// if (r > 0 || g > 0 || b > 0) && a > 0 {
// log.Printf("绘制像素: (%d,%d) RGBA(%d,%d,%d,%d)", x, y, r, g, b, a)
// }
idx := (y-bounds.Min.Y)*img.Stride + (x-bounds.Min.X)*4
img.Pix[idx] = r
img.Pix[idx+1] = g
img.Pix[idx+2] = b
img.Pix[idx+3] = a
}
}