いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-160 (8ビット グレースケール 画像を作る)

概要

最近画像処理をすることが多いので、8ビット グレースケール 画像をよく作っています。

ImageMagickを使えば、すぐに作れるのですが、Goでも出来るのかなってしらべてみたところ、とても簡単に作れたので忘れないうちにメモメモ。

devlights.hatenablog.com

サンプル

画像は unsplash のものをテストデータとして利用させてもらっています。

download.go

package imaging

import (
    "bytes"
    "io"
    "net/http"
)

type (
    downloder string
)

func (me downloder) download() (*bytes.Buffer, error) {
    var (
        client http.Client
        resp   *http.Response
        buf    = new(bytes.Buffer)
        err    error
    )

    if resp, err = client.Get(string(me)); err != nil {
        return buf, err
    }
    defer resp.Body.Close()

    if _, err = io.Copy(buf, resp.Body); err != nil {
        return buf, err
    }

    return buf, nil
}

grayscale.go

package imaging

import (
    "bytes"
    "image"
    "image/jpeg"
    "os"

    "github.com/devlights/gomy/output"
)

// Grayscale は、Go の標準パッケージ image を利用して 8-bit Grayscale JPEG を作成するサンプルです.
//
// REFERENCES:
//   - https://riptutorial.com/go/example/31693/convert-color-image-to-grayscale
//   - https://pkg.go.dev/image@go1.17#example-package
//   - https://unsplash.com/photos/hgUcyDIWPfM
func Grayscale() error {
    const (
        imgUrl = "https://unsplash.com/photos/hgUcyDIWPfM/download?force=true"
    )

    //////////////////////////////////////////////////////
    // Download
    //////////////////////////////////////////////////////
    var (
        dl  = downloder(imgUrl)
        buf *bytes.Buffer
        err error
    )

    if buf, err = dl.download(); err != nil {
        return err
    }
    output.Stdoutl("[download]", buf.Len())

    //////////////////////////////////////////////////////
    // Decode
    //////////////////////////////////////////////////////
    var (
        img    image.Image
        imgFmt string
    )

    if img, imgFmt, err = image.Decode(buf); err != nil {
        return err
    }
    output.Stdoutl("[image.Decode]", imgFmt, img.Bounds().Size())

    //////////////////////////////////////////////////////
    // Convert
    //////////////////////////////////////////////////////
    var (
        bounds  = img.Bounds()
        grayImg *image.Gray
    )

    grayImg = image.NewGray(bounds)
    for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
        for x := bounds.Min.X; x < bounds.Max.X; x++ {
            grayImg.Set(x, y, img.At(x, y))
        }
    }

    //////////////////////////////////////////////////////
    // Output
    //////////////////////////////////////////////////////
    var (
        f *os.File
        o = &jpeg.Options{
            Quality: jpeg.DefaultQuality,
        }
    )

    if f, err = os.CreateTemp("", "*.jpg"); err != nil {
        return err
    }
    defer f.Close()

    if err = jpeg.Encode(f, grayImg, o); err != nil {
        return err
    }
    output.Stdoutl("[output]", f.Name())

    return nil
}

実行すると以下のような感じ。

❯ task
task: [run] go run github.com/devlights/try-golang/cmd/trygolang -onetime

ENTER EXAMPLE NAME: imaging_grayscale

[Name] "imaging_grayscale"
[download]           5474192
[image.Decode]       jpeg (3665,5498)
[output]             C:\Users\xxxx\AppData\Local\Temp\889251550.jpg


[Elapsed] 3.219233s

元ファイルがこれ。

unsplash.com

上の処理を通した後の画像がこれ。

f:id:gsf_zero1:20210830153809j:plain

参考資料


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com