ImageMagick 可以在 Windows PowerShell 上运行,但不能用 go 运行

我需要用 ImageMagick 添加水印,出于某种原因,我需要用 golang 运行它。


这是我的代码片段


package main


import (

    "fmt"

    "os"

    "os/exec"

    "path/filepath"

    "runtime"

    "strings"

)


func main() {

    currentDir, _ := os.Getwd()


    sourceImg := os.Args[1]


    sourceName := filepath.Base(sourceImg)

    sourceExt := filepath.Ext(sourceImg)

    imgNameWithoutExt := strings.Replace(sourceName, sourceExt, "", 1)

    targetImgName := imgNameWithoutExt + "_wm" + sourceExt

    targetImg := filepath.Join(filepath.Dir(sourceImg), targetImgName)


    command := "bash"

    secondParam := "-c"

    // In macOS or Linux, use backslash to escape parenthesis

    cmdStr := `magick "` + sourceImg + `" -set option:watermarkWidth "%[fx:int(w*0.25)]" -alpha set -background none \\( -fill "#FFFFFF80" -stroke "#FF000080" -strokeWidth 3 -undercolor "#FF000080" -font "arial.ttf" -size "%[watermarkWidth]x" label:"This is watermark" -gravity center -geometry +10+10 -rotate -30 \\) -composite -quality 40 "` + targetImg + `"`


    if runtime.GOOS == "windows" {

        sourceImg = strings.ReplaceAll(sourceImg, "\\", "\\\\")

        targetImg = strings.ReplaceAll(targetImg, "\\", "\\\\")

        // In PowerShell, use babckstick (`) to escape parenthesis

        command = "cmd"

        secondParam = "/c"

        cmdStr = `magick "` + sourceImg + `" -set option:watermarkWidth "%[fx:int(w*0.25)]" -alpha set -background none ` + "`(" + ` -fill "#FFFFFF80" -stroke "#FF000080" -strokeWidth 3 -undercolor "#FF000080" -font "arial.ttf" -size "%[watermarkWidth]x" label:"This is watermark" -gravity center -geometry +10+10 -rotate -30 ` + "`)" + ` -composite -quality 40 "` + targetImg + `"`

    }


    fmt.Println(cmdStr)


    cmd := exec.Command(command, secondParam, cmdStr)

    cmd.Dir = currentDir

    ouput, err := cmd.Output()

    if err != nil {

        fmt.Println("Error:", ouput, err.Error())

    } else {

        fmt.Println("Watermark was successfully added!")

    }

}

因为我os.Getwd()在代码中使用了,所以我们不能直接运行它go run main.go,而是应该构建一个可执行文件

http://img1.mukewang.com/63841dbd0001365206570385.jpg



拉莫斯之舞
浏览 92回答 1
1回答

慕森卡

您没有使用PowerShell从您的 Go 应用程序内部调用您的可执行文件,您正在使用cmd.exe,它具有不同的语法规则(它不识别`(反引号)作为转义字符,%是一个元字符,不支持转义"为\", ...)因此,由于您错误地将专为powershell.exe(Windows PowerShell CLI)设计的命令行传递给cmd.exe旧版 Windows shell,由于语法差异,它失败了。因此,替换:    command = "cmd"     secondParam = "/c"和:    command = "powershell.exe"     secondParam = "-c"此外,考虑在 之前放置以下参数-c,以增加稳健性:   "-ExecutionPolicy", "Bypass", "-NoProfile"请参阅文档powershell.exe。退一步说:您的可执行调用不使用任何shell 功能(例如重定向到文件、通过管道连接多个命令,...),因此您可以直接调用,将其及其所有参数单独magick 传递给exec.Command(),从而加快速度操作并避免转义的需要。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go