0
votes

I am using the image package to decode images and determine their format (e.g. jpg or png) however I wish to go one level deeper and I'd like to tell if the png is actually a png8 or png24.

What would be the right way of doing this using Go?

(Update 1)

Currently I am reading able to decode the image, and I'm wondering how to grab the colour model from here:

fname := "img.jpg"
f, err := os.Open(fname)
_, format, err := image.Decode(f)
if err != nil {
    log.Fatal(err)
}

fmt.Println(format, "format")
1
The standard lib and its API does not expose such details. You have to either look in their source, copy and modify, or look for a 3rd party lib.icza
Knowing this much about Go → · but only checking the documentation: it isn't as simple as checking the reported color model of your image?Jongware
That's what I thought after reading the docs for a while now. I think I'll try to port this from PHP: stackoverflow.com/questions/57547818/php-detect-png8-or-png24 - seems like a good solutionTamas
@usr2564301 - I'm new to Go and I tried to get the color model but I couldn't get it to work. I'm as far as decoding the image but I'm not sure how to proceed. I'll add more info to the original question.Tamas

1 Answers

1
votes

Try this, just keep in mind it is without sanity checks

package main

import (
    "errors"
    "fmt"
    _ "image/png"
    "os"
)

func pngType(f *os.File) (string, error) {
    f.Seek(24, 0)
    b := make([]byte, 1)
    f.Read(b)
    c := make([]byte, 1)
    f.Read(c)

    bitDepth := b[0]
    colorType := c[0]

    if bitDepth == 8 && colorType == 3 {
        return "PNG8", nil
    }

    if bitDepth == 8 && colorType == 2 {
        return "PNG24", nil
    }

    if bitDepth == 8 && colorType == 6 {
        return "PNG32", nil
    }

    return "", errors.New("unknown_type")
}

func main() {
    f, _ := os.Open("img.png")
    t, _ := pngType(f)

    fmt.Printf("The type is `%s`.\n", t)
}

You can check specs for reference