为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
拉莫斯之舞 2022-11-28 10:32:01
我需要用 ImageMagick 添加水印,出于某种原因,我需要用 golang 运行它。这是我的代码片段package mainimport (    "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,而是应该构建一个可执行文件
查看完整描述

1 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

没有使用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(),从而加快速度操作并避免转义的需要。


查看完整回答
反对 回复 2022-11-28
  • 1 回答
  • 0 关注
  • 91 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信