Help us understand the problem. What is going on with this article?

Go言語の標準パッケージだけで画像処理をする その1 (入出力)

ZOZOテクノロジーズ #5 Advent Calendar 2019の記事です。
昨日は @satto_sann さんの「Alexaのアカウントリンクをデバッグする方法」でした。

本記事では、Go言語の標準パッケージでの画像処理について書いていきます。

はじめに

最初に明言しておきますが、これはGo言語での画像処理を勧める記事ではありません。
あくまで、自分にメリットがありそうという方のみ参考にしていただければと思います。

自分はZOZOテクノロジーズの中でも、アパレル生産におけるファクトリーオートメーションという分野を担当しています。

担当分野が広いというのと、自動化の対象がアパレル関係ということもあり、
開発環境を実行環境に入れることができなかったり、実行環境により使う言語を変えたりと手間がかかってしまう場面がよく発生します。

特に画像処理関係でプロトタイプをサクッと作る際には、開発環境をその都度作るのが面倒だったりします。

そんな手間を無くせないかなーとふと思い、本記事シリーズを書くことにしました。

A36FD16C-29EF-4FA3-89A6-717EDFF2409B.jpeg

Go言語 image パッケージ
Package 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 (回転、反転)」という記事を書きます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした