我正在尝试构建一个用Go编写的云函数,该函数将使用Google的Cloud Functions基础结构中可用的ImageMagick库来合成和处理多个图像,以生成最终的输出图像。
问题的根源是我要使用的ImageMagick函数可用,但是它需要多个不同的输入才能起作用。我的输入是存储桶中的对象。
os / exec Cmd结构允许您通过使用“ ExtraFiles”数组来执行此操作,并且我知道如何将这些额外的文件提供给ImageMagick命令。
但是,“ ExtraFiles”数组只想存储os.File实例,而GCP Storage Client在打开文件时为您提供“ Reader”实例。
lastModifiedFileName
答案 0 :(得分:1)
对于以后遇到这个问题的任何人-我找到了一种解决方法。我不为它感到兴奋,但是它是实用的。
从本质上讲,我能够读取存储Readers的内容,然后在Cloud Functions上下文中创建自己的os.File对象。然后,将该os.File传递给exec.Cmd调用。绝对不理想,但是下面是代码:
func Overlay(ctx context.Context, inputBucket, outputBucket, background string, foreground string, output string) (string, error) {
// Retrieve the Background Image from the storage API
backgroundBlob := storageClient.Bucket(inputBucket).Object(background)
backgroundImg, err := backgroundBlob.NewReader(ctx)
if err != nil {
return "", fmt.Errorf("backgroundImg: %v", err)
}
// Read the contents of the file into a variable
backgroundSlurp, err := ioutil.ReadAll(backgroundImg)
if err != nil {
return "", fmt.Errorf("readFile: unable to read data from bucket %q, file %q: %v", inputBucket, background, err)
}
// Write the contents of Background Image to an os.File instance
err = ioutil.WriteFile(fmt.Sprintf("/tmp/%s",background), backgroundSlurp, 0644)
if err != nil {
return "", fmt.Errorf("backgroundImg: %v", err)
}
// Open the os.File instance to pass it on to os.exec later
backgroundFile, err := os.Open(fmt.Sprintf("/tmp/%s",background))
if err != nil {
return "", fmt.Errorf("backgroundFile: %v", err)
}
foregroundBlob := storageClient.Bucket(inputBucket).Object(foreground)
foregroundImg, err := foregroundBlob.NewReader(ctx)
if err != nil {
return "", fmt.Errorf("foregroundImg: %v", err)
}
// Read the contents of the file into a variable
foreroundSlurp, err := ioutil.ReadAll(foregroundImg)
if err != nil {
return "", fmt.Errorf("readFile: unable to read data from bucket %q, file %q: %v", inputBucket, foreground, err)
}
// Write the contents of Foreground Image to an os.File instance
err = ioutil.WriteFile(fmt.Sprintf("/tmp/%s",foreground), foreroundSlurp, 0644)
if err != nil {
return "", fmt.Errorf("foregroundImg: %v", err)
}
// Open the os.File instance to pass it on to os.exec later
foregroundFile, err := os.Open(fmt.Sprintf("/tmp/%s",foreground))
if err != nil {
return "", fmt.Errorf("foregroundFile: %v", err)
}
outputBlob := storageClient.Bucket(outputBucket).Object(output)
outputImg := outputBlob.NewWriter(ctx)
defer outputImg.Close()
// Set up some additional file handles since we're delaqing with more inputs than STDIN Can cope with
cmd := exec.Command("convert", "fd:3", "fd:4", "-composite", "-")
cmd.Stdout = outputImg
cmd.ExtraFiles = append(cmd.ExtraFiles,backgroundFile)
cmd.ExtraFiles = append(cmd.ExtraFiles,foregroundFile)
if err := cmd.Run(); err != nil {
return "", fmt.Errorf("cmd.Run: %v", err)
}
log.Printf("Blurred image has been uploaded to %s", outputBlob.ObjectName())
return outputBlob.ObjectName(), nil
}