Go: decode a Sume WebP image with golang.org/x/image/webp

Go's image package decodes PNG and JPEG out of the box; WebP needs golang.org/x/image/webp. Decode a Sume image URL and read its size without a re-encode.

4 min readSume
All posts

Use golang.org/x/image/webp. Its package page shows a decoder only: Decode returns an image.Image, and DecodeConfig returns the colour model and dimensions without decoding the pixels. There is no encoder in that package, so if you need WebP back out, you need another library or you stay in PNG or JPEG.

This matters for Sume because the image API can return WebP. Recraft V4 lists only webp as its output_format, and every other catalog model accepts png, jpeg or webp. If your Go service only imports image/png and image/jpeg, a WebP body fails with an unknown-format error.

What does a complete decode look like?

Fetch data[0].url from a 200 response, then decode the body. The blank import for the format registers the decoder, and the import path of the package is the same one the page documents. Run it with go run main.go <image-url> inside a module that has run go get golang.org/x/image/webp.

DecodeConfig is the cheap call. Use it when you only want to verify that a generated image has the aspect ratio you asked for, and Decode when you need pixels.

package main

import (
	"fmt"
	"net/http"
	"os"

	"golang.org/x/image/webp"
)

func main() {
	resp, err := http.Get(os.Args[1])
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	cfg, err := webp.DecodeConfig(resp.Body)
	if err != nil {
		fmt.Println("not a WebP:", err)
		return
	}
	fmt.Printf("%dx%d\n", cfg.Width, cfg.Height)
}

Or skip WebP and ask for PNG

If the service never needs WebP, set output_format to png or jpeg in the request and keep the standard library decoders. Sume checks the parameter against the model's catalog entry, and an unsupported value comes back as 400 unsupported_parameter, not a silent fallback. Read data[].media_type in the response if you want to choose the decoder at run time instead of guessing from the URL.

Status codes before pixels

A Sume image call blocks for up to 30 seconds. A 200 means the body has data[].url. A 202 means the job is still running and the image lives behind the result_url in the job envelope. A 502 means the job failed for good. Check resp.StatusCode first; decoding a JSON error envelope as an image is the most common reason a new integration prints a confusing decode error. The jobs guide covers the polling side.

For cost tracking, the same 200 body has usage.cost, the billed USD amount. Sume bills image models per image, and the token counts in usage are always 0, so decode the cost field and ignore the token fields in a Go struct. Keep one http.Client with a timeout above 30 seconds for the whole service, so a request that Sume holds for the full wait does not die on your own deadline before the 202 arrives.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume