我正在尝试从AWS S3读取png文件,该文件返回[]byte
。
但是,我无法从bytes.NewReader()
中读取png。这是我的代码
config := aws.Config{
Region: aws.String(region),
}
sess := session.Must(session.NewSession(&config))
svc := s3.New(sess)
s3Output, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
return make([]byte, 0), err
}
buf := new(bytes.Buffer)
buf.ReadFrom(s3Output.Body)
imgReader := bytes.NewReader(buf.Bytes())
_, format, err := image.DecodeConfig(imgReader )
if err != nil {
return nil, err
}
fmt.Println(format)
img, err := png.Decode(imgReader)
if err != nil {
return nil, err
}
格式返回png
,但返回错误png: invalid format: not a PNG file
我尝试使用文件,但成功
file, err := os.Open(ImageFile)
if err != nil {
log.Fatal(err)
}
// decode jpeg into image.Image
img, err := png.Decode(file)
if err != nil {
log.Fatal(err)
}
file.Close()
我该如何解决?
更新
这是s3Output
{
AcceptRanges: "bytes",
Body: buffer(0xc04220e040),
ContentLength: 102104,
ContentType: "image/png",
ETag: "\"d1b5490e26ddd6259cd5d17fa3c4dc6b\"",
LastModified: 2018-08-16 09:30:35 +0000 UTC,
Metadata: {
}
}
答案 0 :(得分:1)
尝试使用AWS S3下载管理器,它将使您可以直接下载图像以及元数据和在aws s3上上传的图像的位置,
buff := &aws.WriteAtBuffer{}
s3dl := s3manager.NewDownloader(sess)
_, err := s3dl.Download(buff, &s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
if err != nil {
log.Printf("Could not download from S3: %v", err)
}
使用s3Output.Body
将为您提供输出,因为它已经以字节为单位,并带有上载的文件内容。因此,您需要在将图像转换为字节后使用图像创建缓冲区。函数png.Decode
在io.Reader上的工作方式为:
func Decode(r io.Reader) (image.Image, error)
Decode从r读取PNG图像,并将其作为image.Image返回。的 返回的图像类型取决于PNG内容。
检查this example,其中使用png.Decode
将Base64代码转换为图像。
AWS S3提供了特殊的下载管理器来直接执行从存储桶中下载文件的操作。有关更多信息,Check AWS S3 Basic bucket operations
答案 1 :(得分:0)
我不知道为什么,但是如果我使用 s3Output.Body
而不是字节,则会得到正确的结果。
config := aws.Config{
Region: aws.String(region),
}
sess := session.Must(session.NewSession(&config))
svc := s3.New(sess)
s3Output, err := svc.GetObject(&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
})
img, err := png.Decode(s3Output.Body)
您可以解释为什么会发生这种情况,我很乐意将您的答案标记为正确答案:)
事实证明,读者会在image.DecodeConfig
中被改变
所以,如果我使用
imgFormat := bytes.NewReader(buf.Bytes())
imgReader := bytes.NewReader(buf.Bytes())
_, format, err := image.DecodeConfig(imgFormat)
if err != nil {
return nil, err
}
fmt.Println(format)
img, err := png.Decode(imgReader)
if err != nil {
return nil, err
}
fmt.Println(img)
return nil, nil
它不会抛出任何错误。我现在会坚持使用,但是如果有更好的方法,请随时发布答案。