回答編集履歴

2

追記

2020/09/29 05:24

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -23,3 +23,57 @@
23
23
  fileオブジェクトはSeekerインターフェースを満たすのでSeekによって巻き戻しをすれば
24
24
 
25
25
  両方の処理に通すことができます。
26
+
27
+
28
+
29
+ ## 追記
30
+
31
+
32
+
33
+ 画像がでかい可能性があり、Seekableではないストリームから画像を
34
+
35
+ よみつつメタ情報も欲しい場合は以下の様に書きます。
36
+
37
+
38
+
39
+ [https://play.golang.org/p/sLdrO9r9MaF](https://play.golang.org/p/sLdrO9r9MaF)
40
+
41
+ ```go
42
+
43
+ func ImageDecode(r io.Reader) (image.Config, image.Image, error) {
44
+
45
+ header := bytes.NewBuffer(nil)
46
+
47
+ info, err := png.DecodeConfig(io.TeeReader(r, header))
48
+
49
+ if err != nil {
50
+
51
+ return image.Config{}, nil, err
52
+
53
+ }
54
+
55
+ img, err := png.Decode(io.MultiReader(header, r))
56
+
57
+ if err != nil {
58
+
59
+ return image.Config{}, nil, err
60
+
61
+ }
62
+
63
+ return info, img, nil
64
+
65
+ }
66
+
67
+ ```
68
+
69
+
70
+
71
+ - TeeReaderは読まれた内容のコピーを第二引数のWriterに書くという挙動をとります。
72
+
73
+ - DecodeConfigは数十バイト以下のヘッダしか読みませんのでheaderバッファにはそのコピーが入ります。
74
+
75
+ - 画像のDecodeにはheaderの内容とまだ読んでいない残りの画像データをつないでReaderにするMultiReaderでラップしたものを読ませます。
76
+
77
+
78
+
79
+ これで巻き戻しを使わずに効率よくメタ情報を得つつ、画像のデコードができます。

1

補足追記

2020/09/29 05:24

投稿

nobonobo
nobonobo

スコア3367

test CHANGED
@@ -14,7 +14,9 @@
14
14
 
15
15
  Decodeには両方の読み込みが必要です。
16
16
 
17
- DecodeConfigにはHeaderだけを読んで画像ファイルのいろんな情報を得られます
17
+ DecodeConfigにはHeaderだけを読んで画像ファイルのいろんな情報を得られますが、
18
+
19
+ Header分だけ読み進んでしまうので、そのまま引き続きfileをDecodeに渡してもHeaderが読めないことでエラーになります。つまり、DecodeやDecodeConfigで要求される引数の型io.Readerは読み進める以外のことはしません(一方通行)。
18
20
 
19
21
 
20
22