How do I detect file type of input that's piped into a Go program that expects either images or gifs?

huangapple go评论135阅读模式
英文:

How do I detect file type of input that's piped into a Go program that expects either images or gifs?

问题

我有一个命令行工具,可以接受文件路径或URL(可以是GIF或图像)作为输入。目前,我通过它们的扩展名(路径末尾的.gif.jpg等)来区分这两者,但是如果输入是从命令行中的其他进程中传输的,我不知道该如何区分。

例如,在下面的示例中,myGoProgram 如何知道管道输入是 .png 还是 .gif

cat image.png | ./myGoProgram -

这是我目前如何使用 image Go 模块解码管道输入的图像:

decodedImg, _, err := image.Decode(os.Stdin)

...同样,使用 image/gif Go 模块解码 GIF 的方式如下:

decodedGif, err = gif.DecodeAll(os.Stdin)

但是我不明白如何从 os.Stdin 中知道它是 GIF 还是图像。

英文:

I have a cli tool that accepts input in the form of file paths or urls (which can be gifs or images). Currently, I'm differentiating btw the two by their extensions (.gif, .jpg etc at the end of the paths), but I'm stumped on how to do that if the input is piped from a different process in the command line.

For instance, how will myGoProgram know the piped input is a .png or a .gif in the example below?

cat image.png | ./myGoProgram -

Here's how I'm decoding piped stdin for an image using the image go module right now:

decodedImg, _, err := image.Decode(os.Stdin)

...And the same with a decoding a gif through the image/gif go module:

decodedGif, err = gif.DecodeAll(os.Stdin)

But I don't understand how I'm supposed to know if it's a gif or an image from os.Stdin

答案1

得分: 3

通过@mkopriva提供的问题,我能够找到一个解决方案。

我区分图像、gif和无效输入的整体逻辑如下:

// 导入:
import (
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

// -----
// 逻辑:
var pipedInputTypes = []string{
	"image/png",
	"image/jpeg",
}
var inputIsGif bool

pipedInputBytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
	log.Fatalf("无法读取管道输入:%v", err)
}

fileType := http.DetectContentType(pipedInputBytes)
invalidInput := true

if fileType == "image/gif" {
	inputIsGif = true
	invalidInput = false
} else {
	for _, inputType := range pipedInputTypes {
		if fileType == inputType {
			invalidInput = false
			break
		}
	}
}

if invalidInput {
	log.Fatalf("无法读取类型为\"%v\"的管道输入", fileType)
}

if inputIsGif {
    // 使用pipedInputBytes的Gif程序逻辑
} else {
    // 使用pipedInputBytes的图像程序逻辑
}
英文:

Was able to work out a solution with the help of the question referred by @mkopriva

Overall logic for how I differentiated btw images, gifs and invalid inputs:

// imports:
import (
	"io/ioutil"
	"log"
	"net/http"
	"os"
)

// -----
// logic:
var pipedInputTypes = []string{
	"image/png",
	"image/jpeg",
}
var inputIsGif bool

pipedInputBytes, err := ioutil.ReadAll(os.Stdin)
if err != nil {
	log.Fatalf("Unable to read piped input: %v", err)
}

fileType := http.DetectContentType(pipedInputBytes)
invalidInput := true

if fileType == "image/gif" {
	inputIsGif = true
	invalidInput = false
} else {
	for _, inputType := range pipedInputTypes {
		if fileType == inputType {
			invalidInput = false
			break
		}
	}
}

if invalidInput {
	log.Fatalf("Cannot read piped input of type \"%v\"", fileType)
}

if inputIsGif {
    // Gif program logic with pipedInputBytes
} else {
    // Image program logic with pipedInputBytes
}

huangapple
  • 本文由 发表于 2022年11月3日 17:21:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/74300644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定