So zeichnen Sie mit Golang gerade Linien und Kurven auf Bildern
1. Einführung
Bei der Grafikverarbeitung müssen wir häufig verschiedene Zeichenvorgänge an Bildern ausführen, z. B. das Zeichnen von geraden Linien und Kurven. In diesem Artikel wird erläutert, wie Sie mit der Golang-Sprache gerade Linien und Kurven auf Bildern zeichnen, und entsprechende Codebeispiele geben.
2. Zeichnen Sie eine gerade Linie
Das Zeichnen einer geraden Linie ist eine der einfachsten grafischen Zeichnungen. Es ist sehr praktisch, das Bildpaket und das Zeichenpaket von Golang zu verwenden, um gerade Linien zu zeichnen. Das Folgende ist ein Beispielcode zum Zeichnen einer geraden Linie:
package main import ( "image" "image/color" "image/draw" "image/jpeg" "os" ) func main() { // 打开图片文件 file, err := os.Open("input.jpg") if err != nil { panic(err) } defer file.Close() // 解码图片 img, err := jpeg.Decode(file) if err != nil { panic(err) } // 创建一个可绘制区域 bounds := img.Bounds() drawImg := image.NewRGBA(bounds) // 复制图片内容到绘制区域 draw.Draw(drawImg, bounds, img, bounds.Min, draw.Src) // 绘制直线 lineColor := color.RGBA{255, 0, 0, 255} // 红色直线 start := image.Point{100, 100} // 起点坐标 end := image.Point{300, 300} // 终点坐标 drawLine(drawImg, start, end, lineColor) // 保存绘制后的图片 outFile, err := os.Create("output.jpg") if err != nil { panic(err) } defer outFile.Close() jpeg.Encode(outFile, drawImg, &jpeg.Options{Quality: 100}) } // 绘制直线 func drawLine(img draw.Image, start, end image.Point, c color.Color) { dx := abs(end.X - start.X) dy := abs(end.Y - start.Y) sx := 0 if start.X < end.X { sx = 1 } else { sx = -1 } sy := 0 if start.Y < end.Y { sy = 1 } else { sy = -1 } err := dx - dy for { img.Set(start.X, start.Y, c) if start.X == end.X && start.Y == end.Y { break } e2 := 2 * err if e2 > -dy { err -= dy start.X += sx } if e2 < dx { err += dx start.Y += sy } } } // 计算绝对值 func abs(x int) int { if x < 0 { return -x } return x }
Im obigen Code öffnen wir zunächst die Bilddatei, die gezeichnet werden muss, und dekodieren sie in ein Bildobjekt. Anschließend erstellen wir einen Zeichenbereich und kopieren den Bildinhalt in den Zeichenbereich. Als nächstes rufen wir die Funktion drawLine()
auf, um eine gerade Linie zu zeichnen. Die Funktion drawLine()
函数来绘制直线。
drawLine()
函数使用的是Bresenham算法,该算法通过逐步迭代的方式来绘制线段。通过设置起点和终点的坐标,我们可以在绘制区域中绘制一条直线。最后,我们将绘制后的图片保存到文件中。
三、绘制曲线
绘制曲线相对而言较为复杂,但也可以使用Golang的image和draw包来实现。下面是一个绘制贝塞尔曲线的示例代码:
package main import ( "image" "image/color" "image/draw" "image/jpeg" "math" "os" ) func main() { // 打开图片文件 file, err := os.Open("input.jpg") if err != nil { panic(err) } defer file.Close() // 解码图片 img, err := jpeg.Decode(file) if err != nil { panic(err) } // 创建一个可绘制区域 bounds := img.Bounds() drawImg := image.NewRGBA(bounds) // 复制图片内容到绘制区域 draw.Draw(drawImg, bounds, img, bounds.Min, draw.Src) // 绘制贝塞尔曲线 curveColor := color.RGBA{0, 255, 0, 255} // 绿色曲线 controlPoints := []image.Point{ {100, 100}, // 控制点1 {200, 300}, // 控制点2 {300, 100}, // 控制点3 } drawCurve(drawImg, controlPoints, curveColor) // 保存绘制后的图片 outFile, err := os.Create("output.jpg") if err != nil { panic(err) } defer outFile.Close() jpeg.Encode(outFile, drawImg, &jpeg.Options{Quality: 100}) } // 绘制贝塞尔曲线 func drawCurve(img draw.Image, controlPoints []image.Point, c color.Color) { step := 0.01 // 步长 stepNum := int(1 / step) + 1 for t := 0; t <= stepNum; t++ { tf := float64(t) * step x, y := calculateBezier(controlPoints, tf) if x >= 0 && y >= 0 && x < img.Bounds().Dx() && y < img.Bounds().Dy() { img.Set(x, y, c) } } } // 计算贝塞尔曲线上的点 func calculateBezier(controlPoints []image.Point, t float64) (x, y int) { n := len(controlPoints) - 1 x = 0 y = 0 for i := 0; i <= n; i++ { coeff := binomialCoefficient(n, i) * math.Pow(1-t, float64(n-i)) * math.Pow(t, float64(i)) x += int(float64(controlPoints[i].X) * coeff) y += int(float64(controlPoints[i].Y) * coeff) } return x, y } // 计算二项式系数 func binomialCoefficient(n, k int) int { return factorial(n) / (factorial(k) * factorial(n-k)) } // 计算阶乘 func factorial(n int) int { result := 1 for i := 1; i <= n; i++ { result *= i } return result }
上述代码中,首先我们打开需要进行绘制的图片文件,并将其解码为image对象。然后,我们创建一个可绘制的区域,并将图片内容复制到该绘制区域中。接下来,我们调用drawCurve()
函数来绘制贝塞尔曲线。
drawCurve()
drawLine()
verwendet den Bresenham-Algorithmus, der Liniensegmente durch schrittweise Iteration zeichnet. Durch Festlegen der Koordinaten des Start- und Endpunkts können wir im Zeichenbereich eine gerade Linie zeichnen. Abschließend speichern wir das gezeichnete Bild in einer Datei.
3. Kurven zeichnen
rrreee
Im obigen Code öffnen wir zunächst die Bilddatei, die gezeichnet werden muss, und dekodieren sie in ein Bildobjekt. Anschließend erstellen wir einen Zeichenbereich und kopieren den Bildinhalt in den Zeichenbereich. Als nächstes rufen wir die FunktiondrawCurve()
auf, um die Bezier-Kurve zu zeichnen. Die Funktion drawCurve()
verwendet den Bezier-Kurvenalgorithmus, der die entsprechenden Punkte auf der Kurve basierend auf dem gegebenen Kontrollpunktarray und dem Parameter t berechnet. Einzelheiten zu spezifischen Algorithmen finden Sie in der einschlägigen Literatur. Abschließend speichern wir das gezeichnete Bild in einer Datei. Das obige ist der detaillierte Inhalt vonSo zeichnen Sie mit Golang gerade Linien und Kurven auf Bildern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!