I have a code that downloads images from AWS S3, decodes them, and resizes them. The code supports images with PNG and JPG/JPEG formats.
Here is how I download the images from AWS S3:
//downloads an image from S3
func downloadImage(bucket string, item string) error {
file, err := os.Create(strings.Split(item, "/")[len(strings.Split(item, "/"))-1])
if err != nil {
fmt.Println("Unable to open file", err)
return err
}
//create a new AWS session
sess, err := session.NewSession(&aws.Config{
Region: aws.String("eu-west-1")},
)
//create the s3 downloader
downloader := s3manager.NewDownloader(sess)
defer file.Close()
//download the image from S3
numBytes, err := downloader.Download(file,
&s3.GetObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(item),
})
if err != nil {
fmt.Println("Unable to download item", item)
fmt.Println(err)
return err
}
fmt.Println("Downloaded", file.Name(), numBytes, "bytes")
return nil
}
Here is how I decode the images:
file, err := os.Open(image)
if err != nil {
fmt.Println(err)
return err
}
if strings.Split(image, ".")[len(strings.Split(image, "."))-1] == "jpg" ||
strings.Split(image, ".")[len(strings.Split(image, "."))-1] == "jpeg" {
img, err := jpeg.Decode(file)
if err != nil {
fmt.Println(err)
return err
}
file.Close()
}
else if strings.Split(image, ".")[len(strings.Split(image, "."))-1] == "png" {
img, err := png.Decode(file)
if err != nil {
fmt.Println(err)
return err
}
file.Close()
}
The images are downloaded, decoded, and resized successfully. A problem arises when the code downloads some PNG images (not all), and tries to decode them. It can't.
it generates the following error:
png: invalid format: not a PNG file
I am running everything on top of an Ubuntu 16.04. What is weird is that if I open this image using Image viewer, it generates the same error. However, if I open using any other program, such as: ImageMagick, the image opens without any complaint.
How can I overcome this issue in the Golang code?
Aparently, even though the extension name is .png, and its content type is PNG, it is not necessarily a PNG image. The only way to know for sure is by examining the image header.
One way to overcome this problem with GoLang is to use the general image.Decode()
function which detects the image type based on a registry as suggested by @icza