用golang給圖片加浮水印

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

前言

大前天上班的時候,坐在旁邊的同事需要一批有浮水印的圖片來測試模型。然後我就主動站出來……
他問我怎麼加,我說用golang可以。可為啥我不用更容易實現的Python呢……可能是為了裝逼。

代碼

WaterMark.go | Gist

package mainimport (    "bytes"    "fmt"    "strings"    "io/ioutil"    "os"    "path"    "math"    "math/rand"    "time"    "image"    "image/color"    "image/draw"    "image/jpeg"    "image/png"    "github.com/gonum/plot/vg"    "github.com/gonum/plot/vg/vgimg")func init() {    rand.Seed(time.Now().UnixNano())}// WaterMark for adding a watermark on the imagefunc WaterMark(img image.Image, markText string) (image.Image, error) {    // image's length to canvas's length    bounds := img.Bounds()    w := vg.Length(bounds.Max.X) * vg.Inch / vgimg.DefaultDPI    h := vg.Length(bounds.Max.Y) * vg.Inch / vgimg.DefaultDPI    diagonal := vg.Length(math.Sqrt(float64(w*w + h*h)))    // create a canvas, which width and height are diagonal    c := vgimg.New(diagonal, diagonal)    // draw image on the center of canvas    rect := vg.Rectangle{}    rect.Min.X = diagonal/2 - w/2    rect.Min.Y = diagonal/2 - h/2    rect.Max.X = diagonal/2 + w/2    rect.Max.Y = diagonal/2 + h/2    c.DrawImage(rect, img)    // make a fontStyle, which width is vg.Inch * 0.7    fontStyle, _ := vg.MakeFont("Courier", vg.Inch*0.7)    // repeat the markText    markTextWidth := fontStyle.Width(markText)    unitText := markText    for markTextWidth <= diagonal {        markText += " " + unitText        markTextWidth = fontStyle.Width(markText)    }    // set the color of markText    c.SetColor(color.RGBA{0, 0, 0, 122})    // set a random angle between 0 and π/2    θ := math.Pi * rand.Float64() / 2    c.Rotate(θ)    // set the lineHeight and add the markText    lineHeight := fontStyle.Extents().Height * 1    for offset := -2 * diagonal; offset < 2*diagonal; offset += lineHeight {        c.FillString(fontStyle, vg.Point{X: 0, Y: offset}, markText)    }    // canvas writeto jpeg    // canvas.img is private    // so use a buffer to transfer    jc := vgimg.PngCanvas{Canvas: c}    buff := new(bytes.Buffer)    jc.WriteTo(buff)    img, _, err := image.Decode(buff)    if err != nil {        return nil, err    }    // get the center point of the image    ctp := int(diagonal * vgimg.DefaultDPI / vg.Inch / 2)    // cutout the marked image    size := bounds.Size()    bounds = image.Rect(ctp-size.X/2, ctp-size.Y/2, ctp+size.X/2, ctp+size.Y/2)    rv := image.NewRGBA(bounds)    draw.Draw(rv, bounds, img, bounds.Min, draw.Src)    return rv, nil}// MarkingPicture for marking picture with textfunc MarkingPicture(filepath, text string) (image.Image, error) {    f, err := os.Open(filepath)    if err != nil {        return nil, err    }    defer f.Close()    img, _, err := image.Decode(f)    if err != nil {        return nil, err    }    img, err = WaterMark(img, text)    if err != nil {        return nil, err    }    return img, nil}func writeTo(img image.Image, ext string) (rv *bytes.Buffer, err error) {    ext = strings.ToLower(ext)    rv = new(bytes.Buffer)    switch ext {    case ".jpg", ".jpeg":        err = jpeg.Encode(rv, img, &jpeg.Options{Quality: 100})    case ".png":        err = png.Encode(rv, img)    }    return rv, err}func main() {    if len(os.Args) < 3 {        panic(fmt.Errorf("Please using like this:$ %s [file or directory] [text]", os.Args[0]))    }    target := os.Args[1]    text := os.Args[2]    if stat, err := os.Stat(target); err == nil && stat.IsDir() {        files, _ := ioutil.ReadDir(target)        for _, fn := range files {            img, err := MarkingPicture(path.Join(target, fn.Name()), text)            if err != nil {                continue            }            ext := path.Ext(fn.Name())            base := strings.Split(fn.Name(), ".")[0] + "_marked"            f, err := os.Create(base + ext)            if err != nil {                panic(err)            }            buff, err := writeTo(img, ext)            if err != nil {                panic(err)            }            if _, err = buff.WriteTo(f); err != nil {                panic(err)            }        }    } else {        img, err := MarkingPicture(target, text)        if err != nil {            panic(err)        }        ext := path.Ext(target)        base := strings.Split(path.Base(target), ".")[0] + "_marked"        f, err := os.Create(base + ext)        if err != nil {            panic(err)        }        buff, err := writeTo(img, ext)        if err != nil {            panic(err)        }        if _, err = buff.WriteTo(f); err != nil {            panic(err)        }    }}

圖片效果


圖片發自簡書App

原文連結:用golang給圖片打浮水印 | linw1995

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.