Kripaka Illia
Kripaka Illia

Reputation: 91

image.Decode() unknown format

I have an image that is stored in the filesystem. This file should be decoded to an image and then resized. I know how to resize it, but I can't decode the image. Whatever image path/image I insert in program, it results: image: unknown format.

I've already read all sites about this problem, but none of them did help me. This code represents my simplified program logic (I'd like to understand why this error occurs). In advance, thanks for your attention!

import (
    "bufio"
    "fmt"
    "image"
    "image/png"
    _ "image/jpeg"
    _ "image/png"
    "log"
    "os"
)

func main() {

    file, err := os.Open(`D:\photos\img.png`)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()
    config, format, err := image.DecodeConfig(bufio.NewReader(file))
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(format, config.Height, config.Width, config.ColorModel)
    decodedImg, format, err := image.Decode(bufio.NewReader(file))  // ERROR HERE
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(format,"decode")
    outputFile, err := os.Create(`D:\photos\image.png`)
    if err != nil {
        log.Fatal(err)
    }
    defer outputFile.Close()
    png.Encode(outputFile, decodedImg)

}

Output:

png 512 512 &{0x4ae340}
2020/07/11 09:37:10 image: unknown format

Upvotes: 8

Views: 16012

Answers (1)

Marc
Marc

Reputation: 21035

Both image.Decode and image.DecodeConfig consume the bytes from the passed-in io.Reader.

This means that after DecodeConfig is done, the position in the file is after the bytes already read. image.Decode then comes along with the same underlying file, expects to find the image header, but doesn't.

bufio.NewReader does not reset the position to the beginning of the file (because it can't, it only knows the underlying object is an io.Reader).

You have a few solutions (in order or personal preference):

  • seek back to the beginning of the file before calling image.Decode. eg: newOffset, err := file.Seek(0, 0)
  • don't use image.DecodeConfig (this might not be an option)
  • read the file into a []byte and use a bytes.Buffer
  • open the file again (not particularly efficient)

As a side note, you don't need to wrap the os.File object in a bufio.Reader, it already implements the io.Reader interface.

Upvotes: 17

Related Questions