package vision import ( "image" "image/color" "image/draw" ) // Position 水印位置 type Position int const ( TopLeft Position = iota TopCenter TopRight LeftCenter Center RightCenter BottomLeft BottomCenter BottomRight ) // Watermark 给画布添加图片水印 // mark: 水印画布 // pos: 位置 // opacity: 透明度 (0.0 - 1.0) // padding: 边距 func (c *Canvas) Watermark(mark *Canvas, pos Position, opacity float64, padding int) { if mark == nil || opacity < 0.01 { return } w, h := c.Width(), c.Height() mw, mh := mark.Width(), mark.Height() var x, y int switch pos { case TopLeft: x, y = padding, padding case TopCenter: x, y = (w-mw)/2, padding case TopRight: x, y = w-mw-padding, padding case LeftCenter: x, y = padding, (h-mh)/2 case Center: x, y = (w-mw)/2, (h-mh)/2 case RightCenter: x, y = w-mw-padding, (h-mh)/2 case BottomLeft: x, y = padding, h-mh-padding case BottomCenter: x, y = (w-mw)/2, h-mh-padding case BottomRight: x, y = w-mw-padding, h-mh-padding } // 处理透明度 if opacity >= 0.99 { c.dc.DrawImage(mark.dc.Image(), x, y) } else { mask := image.NewUniform(color.Alpha{uint8(255 * opacity)}) draw.DrawMask(c.dc.Image().(draw.Image), mark.dc.Image().Bounds().Add(image.Pt(x, y)), mark.dc.Image(), image.Point{}, mask, image.Point{}, draw.Over) } } // TextWatermark 给画布添加文字水印 func (c *Canvas) TextWatermark(text string, pos Position, style *DrawStyle, opacity float64, padding int) { // 创建一个临时画布来渲染文字,然后调用 Watermark // 这样可以利用 Watermark 的位置计算逻辑 c.dc.Push() if style != nil && style.FillColor != "" { c.SetColor(style.FillColor) } // 这里简化实现,实际可以先测量文字宽度 tw, th := c.dc.MeasureString(text) temp := New(int(tw)+2, int(th)+2) temp.dc.SetColor(ParseColor(style.FillColor)) temp.dc.DrawString(text, 0, th) c.Watermark(temp, pos, opacity, padding) c.dc.Pop() }