用“浮点数”绘制图像

目前,我正在尝试将现有的 C# 项目转换为 GoLang。该项目采用一个包含一堆坐标的 XML 文件并将它们绘制在图像上。


在 C# 中,在图像上绘制矩形的代码如下:


public void DrawRectangle(Graphics graphics, RectangleShape rectangle)

{

    using (var drawingPen = new Pen(Color.Black))

    {

        graphics.DrawRectangle(

            drawingPen,

            rectangle.StartX,

            rectangle.StartY,

            rectangle.Width,

            rectangle.Height);

    }

}

矩形由以下类定义:


internal sealed class RectangleShape

{

    internal RectangleShape(float startX, float startY, float width, float height)

    {

        this.StartX = startX;

        this.StartY = startY;

        this.Width = width;

        this.Height = height;

    }


    internal float StartX { get; }


    internal float StartY { get; }


    internal float Width { get; }


    internal float Height { get; }

}

这意味着 C# 能够使用定义为 的坐标在图像上绘制矩形float。


现在,我尝试将代码转换为 GoLang,其中我使用以下代码绘制一个矩形:


// DrawRect draws a rectangle with the given dimensions on the given image.

func DrawRect(img *image.RGBA, rect Rectangle) {

    endX := rect.X + rect.Width

    endY := rect.Y + rect.Height


    drawHLine(img, rect.X, rect.Y, endX)

    drawHLine(img, rect.Y, endY, endX)

    drawVLine(img, rect.Y, rect.X, endY)

    drawVLine(img, rect.Y, endX, endY)

}


// PRIVATE: drawHLine draws a horizontal line with the given coordinates on the given image.

func drawHLine(img *image.RGBA, startX, y, endX float32) {

    col := color.RGBA{0x00, 0x00, 0x00, 0xff}


    for ; startX <= endX; startX++ {

        img.Set(startX, y, col)

    }

}


// PRIVATE: drawVLine draws a vertical line with the given coordinates on the given image.

func drawVLine(img *image.RGBA, startY, x, endY float32) {

    col := color.RGBA{0x00, 0x00, 0x00, 0xff}


    for ; startY <= endY; startY++ {

        img.Set(x, startY, col)

    }

}

矩形由以下结构定义:


// Rectangle represents a rectangular shape.

type Rectangle struct {

    X      float32

    Y      float32

    Width  float32

    Height float32

}

Go 中的示例不起作用,因为Set图像上的函数具有以下结构:


func (p *RGBA) Set(x, y int, c color.Color) {

Go 有什么办法可以使用float参数在图像上绘制矩形吗?


一只名叫tom的猫
浏览 135回答 1
1回答

烙印99

该image.Image类型是一个接口,它将图像定义为具有整数坐标的像素,可通过以下Image.At()方法访问:At(x, y int) color.Color您使用的具体实现image.RGBA允许再次使用整数坐标和方法来更改像素RGBA.Set():func (p *RGBA) Set(x, y int, c color.Color)最简单的解决方案是将浮点坐标转换为整数坐标。简单地将浮点转换为整数就是截断,因此您应该使用舍入。0.5在转换之前添加一个简单的舍入。最好是在“开始”坐标上执行此操作,以便循环可以使用整数值,例如:func drawHLine(img *image.RGBA, startX, y, endX float32) {    col := color.RGBA{0x00, 0x00, 0x00, 0xff}    x1, x2 := int(startX + 0.5), int(endX + 0.5)    y1 := int(y + 0.5)    for x := x1; x <= x2; x++ {        img.Set(x, y1, col)    }}请注意,但是这种将浮点坐标转换为整数的“最简单”解决方案可能不是“最佳”。例如,如果您需要在坐标处绘制一条水平线x = 0.1,则上述解决方案将在 处绘制一条线x = 0。一种不同的解决方案可能是在 处画一条“较强”的线x = 0,在 处画一条“较弱”的线,从而给出从远处观察时x = 1该线实际上位于 处的效果。x = 0.1如果线条不是水平和垂直的,这种混叠技术肯定会给出更好的结果,但需要更多的计算(因此速度更慢)。如果您在绘图时确实需要浮动精度,您可以使用第 3 方库,例如github.com/fogleman/gg它允许您传递float64坐标,并且它使用抗锯齿来实现良好的结果。例如,在图像github.com/fogleman/gg上绘制一个矩形image.RGBA,如下所示:var img *image.RGBA = // create your RGBA imagectx := gg.NewContextForRGBA(img)// Set drawing color:ctx.SetColor(color.RGBA{0x00, 0x00, 0x00, 0xff})// Or simply: ctx.SetRGB(0, 0, 0)// Draw rectangle: x, y, w, h are all float64 parametersctx.DrawRectangle(x, y, w, h)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go