Go 언어의 표준 패키지만으로 화상 처리를 한다 그 1 (입출력)

ZOZO 테크놀로지스 #5 Advent Calendar 2019 의 기사입니다.
어제는 @ 빨리 _ 씨씨의 「 Alexa 계정 링크를 디버깅하는 방법 」였습니다.

이 기사에서는 Go 언어의 표준 패키지로 이미지 처리를 작성합니다.

소개



먼저 명확하게 말하지만, 이것은 Go 언어로 이미지 처리를 권장하는 기사가 아닙니다.
어디까지나, 자신에게 메리트가 있다고 하는 분만 참고해 주시면 좋겠습니다.

자신은 ZOZO 테크놀로지스 중에서도, 의류 생산에 있어서 팩토리 오토메이션이라는 분야를 담당하고 있습니다.

담당 분야가 넓다고 하는 것과, 자동화의 대상이 의류 관계라고 하는 일도 있어,
개발 환경을 실행 환경에 넣을 수 없거나 실행 환경에 따라 사용하는 언어를 바꾸거나 수고가 걸리는 장면이 자주 발생합니다.

특히 화상처리 관계로 프로토타입을 바삭하게 만들 때에는 개발환경을 그때마다 만드는 것이 귀찮거나 합니다.

그런 수고를 없애지 않을까-라고 문득 생각해, 본 기사 시리즈를 쓰기로 했습니다.



Go 언어 image 패키지
패키지 이미지

파일 입력



filepath를 이용하는 것으로, os간의 패스 차이를 의식하지 않고 코드를 쓸 수 있습니다.
자신은 아래 소스와 같이 data 파일을 준비하고 그 안에 처리하고 싶은 이미지를 놓고 읽어들이는 방법을 자주 사용합니다.
프로토 타입을 가볍게 움직일 때는 편리합니다.
package main

import (
    "image"
    "log"
    "os"
    "path/filepath"
)

func main() {

    // 実行ファイル直下のパスを取得
    path, _ := os.Getwd()
    dataPath := filepath.Join(path, "data")
    // dataフォルダ直下の画像を一括で読み込む
    jpgPath := filepath.Join(dataPath, "*.jpg")
    jpegPath := filepath.Join(dataPath, "*.jpeg")
    pngPath := filepath.Join(dataPath, "*.png")

    fileList, _ := filepath.Glob(jpgPath)
    f, _ := filepath.Glob(jpegPath)
    fileList = append(fileList, f...)
    f, _ = filepath.Glob(pngPath)
    fileList = append(fileList, f...)

    // 画像を1枚づつ読み込む
    for _, file := range fileList {
        // 画像を読み込む
        img := Input(file)
        println(file, " : " , img)
    }
}

// 画像を読み込む処理
func Input (filePath string) image.Image {

    // 画像を読み込む
    file, err := os.Open(filePath)

    // 画像が読み込めなかった場合
    if err != nil {
        log.Fatal(err)
    }

    // 変換
    img, _, err := image.Decode(file)

    return img
}

파일 출력



출력하고 싶은 확장자에 의해 처리를 나눕니다.
여기에서는 jpg와 png의 출력을 소개합니다.
const imgQt int = 60

func Output (outputImage image.Image, filePath string, format string) {

    dst, err := os.Create(filePath)

    if err != nil {
        log.Fatal(err)
    }

    switch format {
    case "png":
        // PNGの場合
        err = png.Encode(dst, outputImage)
        if err != nil {
            log.Fatal(err)
        }
        break
    case "jpg":
        // JPGの場合
        qt := jpeg.Options{
            Quality:imgQt,
        }
        err = jpeg.Encode(dst, outputImage, &qt)
        if err != nil {
            log.Fatal(err)
        }
        break
    default:
        // 標準で対応していないフォーマットの場合
        log.Fatal("Unsupported format.")
    }
}

픽셀 값 참조



이하에서는 불러온 화상으로부터 화소치를 참조하거나 조작을 행하고 있습니다.
func EditPixel(img image.Image) image.Image {

    // アウトプット画像を定義
    size := img.Bounds()
    // 画像のサイズを変える場合
    // size.Max.X = "任意の数値"
    // size.Max.Y = "任意の数値"
    outputImage := image.NewRGBA(size)

    // 画像の左上から順に画素を読み込む
    for imgRow := size.Min.Y; imgRow < size.Max.Y; imgRow++ {
        for imgCol := size.Min.X; imgCol < size.Max.X; imgCol++ {

            // 画素を取得
            pixel := img.At(imgCol, imgRow)
            println("pixel : ", pixel)
            r, g, b, a := pixel.RGBA()
            println("r : ", r, "g : ", g, "b : ", b, "a : ", a)

            // 画素を操作
            var outputColor color.RGBA64
            // 例(真っ黒な画像にする)
            outputColor.R = 0
            outputColor.G = 0
            outputColor.B = 0
            outputColor.A = 100

            outputImage.Set(imgCol, imgRow, outputColor)
        }
    }

    return outputImage
}

결론



ZOZO 테크놀로지스 #5 Advent Calendar 2019
내일은 「Go 언어의 표준 패키지만으로 화상 처리를 하는 그 2(회전, 반전)」라고 하는 기사를 씁니다.

좋은 웹페이지 즐겨찾기