Skip to content

Instantly share code, notes, and snippets.

@shogo82148
Created April 30, 2018 23:03
Show Gist options
  • Save shogo82148/5af3b90fa965c6b069fe7291b94fc3b5 to your computer and use it in GitHub Desktop.
Save shogo82148/5af3b90fa965c6b069fe7291b94fc3b5 to your computer and use it in GitHub Desktop.
//create.go
package gain
import (
"bufio"
"fmt"
"io"
)
func Create(w io.Writer, width, height int) error {
buf := bufio.NewWriter(w) // XXX: たくさんWriteするときはバッファリングするのがオススメ
buf.WriteString("P2\n")
fmt.Fprintf(buf, "%d\n", width) // XXX: Printfにはio.Writerに直接書き込む版があります
fmt.Fprintf(buf, "%d\n", height)
buf.WriteString("255\n")
for i := 0; i < height; i++ {
for j := 1; j < width; j++ {
if i < height/2 {
buf.WriteString("0 ")
} else {
buf.WriteString("255 ")
}
}
buf.WriteString("0\n")
}
return buf.Flush()
// w.Write(([]byte)("GAIN\n"))
// w.Write(([]byte)(fmt.Sprintf("%d\n", width)))
// w.Write(([]byte)(fmt.Sprintf("%d\n", height)))
// for i := 0; i < height; i++ {
// for j := 1; j < width; j++ {
// if i < height/2 {
// w.Write(([]byte)("0 "))
// } else {
// w.Write(([]byte)("255 "))
// }
// }
// w.Write(([]byte)("0"))
// w.Write(([]byte)("\n"))
// }
}
//main.go
package main
import (
"image"
"image/jpeg"
"io"
"log"
"os"
"github.com/gainings/testGolang/image/gain"
)
func main() {
in, err := os.Create("in.pgm")
if err != nil {
log.Fatal(err)
}
defer in.Close()
//gainフォーマットのファイルを作成する
if err := gain.Create(in, 1000, 1000); err != nil {
log.Fatal(err)
}
//ファイルポインタの気持ちになって初期化
in.Seek(0, io.SeekStart) // XXX: 第二引数に指定する値は定数が定義されています
// in.Seek(0, 0)
gainImg, _, err := image.Decode(in)
if err != nil {
log.Fatal(err)
}
out, err := os.Create("out.jpeg")
if err != nil {
log.Fatal(err)
}
defer out.Close()
opts := &jpeg.Options{Quality: 100}
err = jpeg.Encode(out, gainImg, opts)
if err != nil {
log.Fatal(err)
}
}
//reader.go
package gain
import (
"bufio"
"fmt"
"image"
"image/color"
"io"
"strconv"
"strings"
)
// XXX: GAINフォーマットと似た形式にPGMフォーマットというのがあるので、実装にチャレンジしてみよう
// https://ja.wikipedia.org/wiki/PNM_(%E7%94%BB%E5%83%8F%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88)
const gainHeader = "P2\n"
type decoder struct {
r io.Reader
// XXX: 使ってないよね?
// img image.Image
// width, height int
// tmp [3 * 256]byte
}
type FormatError string
func (e FormatError) Error() string { return "gain: invalid format: " + string(e) }
func (d *decoder) decode() (image.Image, error) {
scanner := bufio.NewScanner(d.r)
header := make([]string, 0, 4) // XXX: 長さがわかっているなら指定したほうがベター
// header := make([]string, 0)
for i := 0; i < 4; i++ {
scanner.Scan()
header = append(header, scanner.Text())
}
if header[0] != "P2" {
return nil, FormatError("not a GAIN file")
}
w, err := strconv.Atoi(header[1])
if err != nil {
return nil, err
}
h, err := strconv.Atoi(header[2])
if err != nil {
return nil, err
}
// XXX: max value が255以外の場合の処理は読者の課題とします
if maxVal := header[3]; maxVal != "255" {
return nil, FormatError(fmt.Sprintf("unsuported max value: %s", maxVal))
}
gray := image.NewGray(image.Rect(0, 0, w, h))
i := 0
for scanner.Scan() {
line := scanner.Text()
cArr := strings.Split(line, " ")
for j, cStr := range cArr {
c, err := strconv.Atoi(cStr)
if err != nil {
return nil, err
}
gray.SetGray(j, i, color.Gray{uint8(c)})
}
i++
}
img := gray
return img, nil
}
func Decode(r io.Reader) (image.Image, error) {
d := &decoder{
r: r,
}
return d.decode() // XXX: エラーハンドリングが抜けてる
// d.img, _ = d.decode()
// return d.img, nil
}
func DecodeConfig(r io.Reader) (image.Config, error) {
cm := color.GrayModel
scanner := bufio.NewScanner(r)
header := make([]string, 0, 4) // XXX: 長さがわかっているなら指定したほうがベター
// header := make([]string, 0)
for i := 0; i < 4; i++ {
scanner.Scan()
header = append(header, scanner.Text())
}
if header[0] != "P2" {
return image.Config{}, FormatError("not a GAIN file")
}
w, err := strconv.Atoi(header[1])
if err != nil {
return image.Config{}, err
}
h, err := strconv.Atoi(header[2])
if err != nil {
return image.Config{}, err
}
return image.Config{
ColorModel: cm,
Width: w,
Height: h,
}, nil
}
func init() {
image.RegisterFormat("gain", gainHeader, Decode, DecodeConfig)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment