【Golang】jpeg画像がプログレッシブ形式か判別する

Go言語を使用してjpeg画像がプログレッシブ形式か判別してみます。
jpeg画像のセグメント情報からプログレッシブ形式を判断できるので、jpegのセグメント情報を取得できるgoのライブラリを使用します。

go-jpeg-image-structureを使用するとjpeg画像の情報を構造体として取得できます。
この構造体の中からセグメント情報を取得して、プログレッシブ形式か判別します。

https://github.com/dsoprea/go-jpeg-image-structure

画像の準備

ベースライン形式とプログレッシブ形式のjpeg画像を用意しました。

  • プログレッシブ形式
  • ベースライン形式

プログレッシブ形式を判別するコード

package main

import (
	"fmt"
	"path/filepath"

	jpegstructure "github.com/dsoprea/go-jpeg-image-structure/v2"
)

func main() {
	jmp := jpegstructure.NewJpegMediaParser()
	_, err := checkProgressive(jmp, "progressive.jpg")
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println()
	_, err = checkProgressive(jmp, "baseline.jpg")
	if err != nil {
		fmt.Println(err)
	}
}

func checkProgressive(jmp *jpegstructure.JpegMediaParser, path string) (bool, error) {
	if ext := filepath.Ext(path); ext != ".jpg" && ext != ".jpeg" {
		return false, fmt.Errorf("%sはjpeg画像ではありません。", path)
	}

	ec, err := jmp.ParseFile(path)
	if err != nil {
		return false, err
	}

	sl := ec.(*jpegstructure.SegmentList)
	fmt.Println(path, "のセグメント")
	for _, segment := range sl.Segments() {
		fmt.Println(segment.MarkerName)
	}

	for _, segment := range sl.Segments() {
		if segment.MarkerName == "SOF2" {
			fmt.Println(path, "はプログレッシブ形式です。")
			return true, nil
		}
	}

	fmt.Println(path, "はプログレッシブ形式ではありません。")
	return false, nil
}

コードを実行すると各jpeg画像のセグメントとプログレッシブかどうかを出力します。

progressive.jpg のセグメント
SOI
APP0
DQT
DQT
SOF2
DHT
DHT
SOS
!SCANDATA
EOI
progressive.jpg はプログレッシブ形式です。

baseline.jpg のセグメント
SOI
APP0
DQT
DQT
SOF0
DHT
DHT
DHT
DHT
SOS
!SCANDATA
EOI
baseline.jpg はプログレッシブ形式ではありません。

jpeg画像がプログレッシブ形式の場合、セグメントにSOF2マーカ一が含まれています。
SOF2マーカ一が見つかったときはプログレッシブ形式と判断します。

参考サイト

jpegフォーマット

jpeg画像作成・プログレッシブ形式変換

go-jpeg-image-structureの使い方

Licensed under CC BY-NC-SA 4.0
Hugo で構築されています。
テーマ StackJimmy によって設計されています。