小程序模板網(wǎng)

io.Reader游標(biāo)引發(fā)的血案

發(fā)布時(shí)間:2018-10-12 10:32 所屬欄目:小程序開(kāi)發(fā)教程

背景

線上運(yùn)行了一個(gè)圖片合成程序,默認(rèn)的小程序二維碼中獎(jiǎng)是小程序LOGO,不滿足需求,所以將微信小程序二維碼和用戶頭像合成在一張圖片。

由于微信圖片有時(shí)候返回的Content-Type不對(duì)應(yīng)(比如內(nèi)容是PNG的,頭確是image/jpeg)所以使用jpeg/png/gif的順序進(jìn)行圖片數(shù)據(jù)解析,哪個(gè)成功就返回解析結(jié)果。

問(wèn)題

總是出現(xiàn)諸如 invalid JPEG format: missing SOI marker

解決過(guò)程

我去查看jpeg.Decode的源碼,如下:

func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
    d.r = r

    // Check for the Start Of Image marker.
    if err := d.readFull(d.tmp[:2]); err != nil {
        return nil, err
    }
    if d.tmp[0] != 0xff || d.tmp[1] != soiMarker {
        return nil, FormatError("missing SOI marker")
    }
...

soiMarker常量

soiMarker  = 0xd8 // Start Of Image.

可以看到判斷了第1個(gè)字節(jié)如果不是 0xff 或者第2個(gè)字節(jié)不是 0xd8 就報(bào)錯(cuò)。打印圖片的bytes前幾個(gè)字節(jié)如下:

[]byte{0xff, 0xd8, 0xff, 0xe0, 0x0, 0x10}

可以看到第1個(gè)字節(jié)和第2個(gè)字節(jié)滿足要求,按理說(shuō)不會(huì)出現(xiàn)這個(gè)問(wèn)題,無(wú)奈只能求助于Google,搜索了

invalid JPEG format: missing SOI marker 關(guān)鍵字出現(xiàn)一篇 Covert base64 string to JPG 引起了我的注意。

打開(kāi)看到答案

You need to create a new reader for each decoder:

pngI, errPng := png.Decode(bytes.NewReader(unbased))

// ...

jpgI, errJpg := jpeg.Decode(bytes.NewReader(unbased))

原來(lái)需要重新創(chuàng)建讀取器,重新創(chuàng)建讀取器后問(wèn)題解決。

后續(xù)

抱著打破砂鍋問(wèn)到底的心態(tài),查看了一下 bytes.Reader 的源碼,發(fā)現(xiàn)游標(biāo)讀取完后并未重置

// Read implements the io.Reader interface.
func (r *Reader) Read(b []byte) (n int, err error) {
    if r.i >= int64(len(r.s)) {
        return 0, io.EOF
    }
    r.prevRune = -1
    n = copy(b, r.s[r.i:])
    r.i += int64(n)
    return
}

Reader定義

type Reader struct {
    s        []byte
    i        int64 // current reading index
    prevRune int   // index of previous rune; or < 0
}

可以看到 r.i 就是游標(biāo)了。問(wèn)題圓滿解決


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開(kāi)源 碼云倉(cāng)庫(kù):starfork
本文地址:http://22321a.com/wxmini/doc/course/24860.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢