Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goにおける画像ファイル処理 / golang.tokyo #19

Harukasan
November 13, 2018

Goにおける画像ファイル処理 / golang.tokyo #19

ImageFlux
Goにおける画像ファイル処理
Golang.Tokyo #19 Talks.2 / 2018-11-03

Harukasan

November 13, 2018
Tweet

More Decks by Harukasan

Other Decks in Technology

Transcript

  1. (Pחֶֽ׷歗⫷ؿ؋؎ٕⳢ椚
    )BSVLBTBO.*$)**4IVOTVLF QJYJW*OD
    HPMBOHUPLZPˋ
    Gopher images were created by Takuya Ueda (https://twitter.com/tenntenn). Licensed under the Creative Commons 3.0 Attributions license.

    View full-size slide

  2. )BSVLBTBO.*$)**4IVOTVLF
    ؾؙءـ吳䒭⠓爡*NBHF'MVY✲噟鿇鿇ꞿ
    ؾؙءـذؙظٗآ٦ؤ吳䒭⠓爡㛁遤䕵㆞
    䎃倜⼼Ⰵ爡
    歗⫷㢌䳔⟃㢩חכծOHJOYծر٦ةⴓ匿㛇湍זו

    View full-size slide

  3. 63-ػًٓ٦ة٦ד㢌䳔䭷㹀
    ꂁ⥋欽63-ػًٓ٦ة׾䭷㹀ׅ׷׌ֽדծ䭁㣐٥簭㼭ծⴖ׶䫙ֹծ㔐鯄ծ
    歗⫷ؿؓ٦وحزך㢌刿הְ׏׋ծⰋגך歗⫷Ⳣ椚׾遤ִתׅկ
    傀㶷أزٖ٦آ׾׉ךתתⵃ欽
    "NB[PO4׾כׄ׭8FC♳ך圫ղז㜥䨽ח呓秛ׁ׸גְ׷ؔٔآشٕ歗
    ⫷ؿ؋؎ٕ׾《䖤דֹתׅկ)5514ח׮㼎䘔׃גְתׅկ
    넝鸞ծ넝ㅷ颵זꂁ⥋
    㣐㺁ꆀךغحؙن٦ٝطحزٙ٦ؙח湫穠ׁ׸׋ٍؗحءُؙٓأةַ
    ׵ծ剑黝⻉ׁ׸׋歗⫷׾ծⰋגךؒٝسِ٦ؠ٦ח넝鸞חꂁ⥋׃תׅկ
    Ꟛ涪؟؎ؙٕ׾⤛鹌ׅ׷ؙٓؐس歗⫷㢌䳔؟٦ؽأ

    View full-size slide

  4. *NBHF'MVYה(P
    ˖ *NBHF'MVYך؝،؝ٝه٦طٝزך㢳ֻכ(Pד㹋鄲ׁ׸גְ׷
    ˖ (P׾䱰欽׃׋ךכك٦أ䪮遭הז׏׋HPUIVNCFSך㹋鄲儗ַ׵

    IUUQTHJUIVCDPNQJYJWHPUIVNCFSխ
    ˖ 넝鸞ַא㸜Ⰻז)551؟٦غ㹋鄲ծ$ך垥彊ٓ؎ـٓٔㄎן⳿׃זוָ〳腉׌׏׋
    ֿהָ㣐ֹז椚歋
    ˖ *NBHF'MVYךקרⰋגך؝ٝه٦طٝزכ)551؟٦غה׃ג㹋鄲

    崧遤ךٙ٦سד鎉ֲהو؎ؙٗ؟٦ؽأ

    View full-size slide

  5. *NBHF1SPDFTTJOHJO(P

    View full-size slide

  6. *NBHF'JMF1SPDFTTJOHJO(P

    View full-size slide

  7. &OEVTFS
    %JTQMBZ
    *OQVU
    .FEJB
    Electromagnetic wave
    8IBUJT*NBHF

    View full-size slide

  8. +1&(
    *NBHFMFGPSNBUT
    1/( (*' 8FC1

    View full-size slide

  9. +1&(
    +1&(+'*' +1&('JMF*OUFSDIBOHF'PSNBU

    +1&(&9*' &YDIBOHFBCMF*NBHF'JMF'PSNBU

    %$5׾欽ְ׋㖇簭䕎䒭
    +1&(垥彊חכ葿瑞꟦׾ろ׭⿑㺘זؿؓ٦وحزָ劢㹀纏
    +'*'رؿ؋ؙزהז׏גְ׋ؿؓ٦وحز׾垥彊⻉׃׋׮ך
    &9*'傈劤ךرآةًٕؕٓ噟歲ָ垥彊⻉׃׋׮ך
    SOI
    APP0 (JFIF)
    APP2

    SOI
    APP1 (EXIF)
    APP2

    +'*'MFTUSVDUVSF &9*'MFTUSVDUVSF
    Tag
    Tag
    Tag

    5*''UBHT

    View full-size slide

  10. R
    +1&(
    IUUQTDPNNPOTXJLJNFEJBPSHXJLJ'JMF$$%QOH
    㛇劤涸ז،ٕ؞ٔؤي
    葿瑞꟦׾:$C$Sח㢌䳔ׅ׷
    ؟ٝفؚׅٔٝ׷
    ـٗحؙחⴓⶴ׃ג%$5㢌䳔ׅ׷
    ꆀ㶨⻉׃ծآؚؠؚחأٍׅؗٝ׷
    عؿوٝ痗〾⻉ח״׷㖇簭׾遤ֲ
    :
    $C$S
    IUUQTFOXJLJQFEJBPSHXJLJ$ISPNB@TVCTBNQMJOH

    View full-size slide

  11. 1/(
    1/( 1PSUBCMF/FUXPSL(SBQIJDT

    (*' (SBQIJDT*OUFSDIBOHF'PSNBU

    (*'
    3(#ծػٖحز䕎䒭ך歗⫷ر٦ة׾׉ךתת㖇簭׃׋歗⫷ؿ؋؎ٕ䕎䒭
    1/(כ[MJC %FBUF
    ծ(*'כ-;8׾⢪׏ג歗⫷ر٦ةך㖇簭׾遤ֲ

    View full-size slide

  12. 8FC1
    8FC1 1PSUBCMF/FUXPSL(SBQIJDT

    71ךؗ٦ؿٖ٦ي歗⫷׾3*''؝ٝذشח鯹ׇ׋歗⫷䕎䒭
    +1&(״׶׮㣐ⴓ倜׃ְךדծ넝ㅷ颵ծ넝㖇簭׾ֲ׋׏גְ׷
    ⹛歗䕎䒭׾ك٦أה׃גְ׷׋׭ծ563#5䕎䒭ך:67ؕٓ٦ٌرٕ׾⢪ֲ
    +1&(ך:$C$Sהכ⦼㚖ָ殯ז׷
    ؟ـ؟ٝفؚٖٔٝءؔכ׃ַ؟ه٦ز׃גְזְךד+1&(״׶׮רװֽ׷
    ֿהָ㢳ְ

    View full-size slide

  13. *NBHF1SPDFTTJOHJO(P

    View full-size slide

  14. JNBHF*NBHF
    type Image interface {
    // ը૾ͷΧϥʔϞσϧΛฦ͢
    ColorModel() color.Model
    // ը૾ͷBoundsΛฦ͢
    Bounds() Rectangle
    // (x, y)ϐΫηϧͷ৭Λฦ͢ɻAt(0,0)͸Ұ൪ࠨ্ɺ

    // At(Bounds().Max.X-1, Bounds().Max.Y-1)͸Ұ൪ӈԼΛฦ͢ɻ
    At(x, y int) color.Color
    }
    歗⫷ر٦ةⰟ鸐ך؎ٝة٦ؿؑ٦أ
    "U Y Z
    ׾欽ְ׷ֿהדծぐ歗稆ך葿׾《䖤דֹ׷
    DPMPS$PMPSכ3(#葿瑞꟦ח㢌䳔׃ג葿׾《䖤דֹ׷

    View full-size slide

  15. JNBHF:$C$S
    type YCbCr struct {
    Y, Cb, Cr []uint8
    YStride int
    CStride int
    SubsampleRatio YCbCrSubsampleRatio
    Rect Rectangle
    }
    :ծ$Cծ$S׉׸׊׸ךꂁ⴨ח؝ٝه٦طٝز׀הךر٦ةָろת׸גְ׷ 1MBOFS

    :$C$S4VCTBNQMF3BUJPכ؟ـ؟ٝفؚٔٝ嫰׾㹀纏ׅ׷
    Y Y Y Y Y Y Y Y 0 … Y Y Y
    Cb Cb Cb Cb Cb Cb Cb 0 0 … Cb Cb Cb
    Cr Cr Cr Cr Cr Cr Cr 0 0 … Cr Cr Cr
    :4USJEF
    $4USJEF

    View full-size slide

  16. JNBHF/3(#"
    type NRGBA struct {
    Pix []uint8
    Stride int
    Rect Rectangle
    }
    3(#"ָ♧אךꂁ⴨ח鑥׭׵׸גְ׷ 1BDLFE3(#"

    3(#"ה/3(#"ך麩ְכ1SFNVMUJQMJFE"MQIBה/PO1SFNVMUJQMJFE"MQIBך麩ְ
    RGBA R G B A R G B A 0 0 R G B …
    4USJEF

    View full-size slide

  17. 歗⫷غحؿ؋הأزٓ؎س
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    R G B A R G B A R G B A R G B A 0 0
    8JEUI
    4USJEF
    歗⫷غحؿ؋כ剑黝⻉ך׋׭4USJEF؟؎ؤד،ٓ؎ًٝٝزׁ׸גְ׷
    Y Z
    ָ妜׃ְהֹכ1JY< Z3FDU.JO:
    4USJEF Y3FDU.JO9
    >

    View full-size slide

  18. *NBHF'MVY1SPDFTTJOHJO(P

    View full-size slide

  19. JNBHFVY4DBO-JOF3FBEFS
    type ScanLineReader interface {
    io.Closer
    // Config returns the configurations of the image planes.
    Config() *Config
    // ReadScanLines reads scan lines into the p for each image component. it
    // reads up to len(p[0]) at once and returns number of bytes read and any
    // error. When the image is YCbCr 4:2:0,
    // ReadScanLines(p) returns
    // p[0]: read scan lines of the Y component.
    // p[1]: read scan lines of the Cb component.
    // p[2]: read scan lines of the Cr component.
    //
    // ReadScanLines returns an error in the same manner of io.Reader.
    ReadScanLines(ctx context.Context, p [][]byte) (n int, err error)
    // ReadLen returns the minimum buffer length that needs to read from this.
    ReadLen() (n int)
    }

    View full-size slide

  20. 3FBE4DBO-JOFT
    㛇劤涸חכ如⯋ꂁ⴨ח䭁䓸׃׋JP3FBEFS
    ؝ٝذؗأز׾欽ְג铣׫鴥׫ךة؎ي،ؐزծٍؗٝإָٕדֹ׷
    // ReadScanLines reads scan lines into the p for each image component…
    ReadScanLines(ctx context.Context, p [][]byte) (n int, err error)
    p[0]: Y Y Y Y Y Y Y Y …
    p[1]: Cb Cb Cb Cb Cb Cb Cb Cb …
    p[2]: Cr Cr Cr Cr Cr Cr Cr Cr …
    +1&(%FDPEFS
    p[0]: R G B A R G B A …
    1/(%FDPEFS

    View full-size slide

  21. 4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    func NewDecoder(src io.ReadCloser, cfg Config) (imageflux.ScanLineReader, error)
    ر؝٦تכJP3FBEFSַ׵غ؎ز⴨׾「ֽ《׏ג歗⫷׾ر؝٦سׅ׷

    View full-size slide

  22. 4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    func NewScaler(src imageflux.ScanLineReader, cfg Config) (imageflux.ScanLineReader, error)
    Ⰵ⸂הז׷4DBO-JOF3FBEFS׾䒷侧חה׏גծ⳿⸂׾铣׫鴥׬׋׭ך4DBO-JOF3FBEFS׾鵤ׅ
    ر؝٦تַ׵ؒٝ؝٦تתדػ؎فٓ؎ٝ׾⡲׷ֿהח״׏ג歗⫷㢌䳔׾遤ֲ

    View full-size slide

  23. 4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    func Write(ctx context.Context, dst io.Writer, src imageflux.ScanLineReader) error
    ؒٝ؝٦تכ4DBO-JOF3FBEFS׾「ֽ《׏גؒٝ؝٦س穠卓׾JP8SJUFSח剅ֹ鴥׬

    View full-size slide

  24. JPEG PNG GIF WebP
    RGB
    Compositing
    Scaling Clipping
    Color Converter
    JPEG PNG GIF WebP
    4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    +1&(׾+1&(ךתתٔ؟؎ؤׅ׷הֹכ葿瑞
    ꟦ך㢌䳔כ遤׻זְ
    ٥

    View full-size slide

  25. JPEG PNG GIF WebP
    RGB
    Compositing
    Scaling Clipping
    Color Converter
    JPEG PNG GIF WebP
    4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    +1&(׾+1&(ךתתٔ؟؎ؤׅ׷הֹכ葿瑞
    ꟦ך㢌䳔כ遤׻זְ
    ػ؎فٓ؎ٝך穄畭כ♧菙涸זJP3FBEFSծ
    JP8SJUFSד㹋鄲ׁ׸גְ׷ךדծIUUQ$MJFOU
    װIUUQ3FTQPOTF8SJUFSהאזּֿהד歗⫷㢌
    䳔فٗؗء׾⡲׷ֿהָדֹ׷
    ٥
    ٥
    IUUQ$MJFOU
    IUUQ3FTQPOTF8SJUFS

    View full-size slide

  26. JPEG PNG GIF WebP
    RGB
    Compositing
    Scaling Clipping
    Color Converter
    JPEG PNG GIF WebP
    4DBO-JOF3FBEFS׾㹋鄲׃׋؝ٝه٦طٝز
    ׾אזֺさ׻ׇ׷
    ؔ٦غ٦ٖ؎さ䧭׾遤ֲꥷכ3(#葿瑞꟦ח㢌
    䳔׃גַ׵さ䧭׾遤ֲ
    ٥

    View full-size slide

  27. *NBHF'MVYחֶֽ׷歗⫷㢌䳔
    ˖ ػ؎فٓ؎ٝⳢ椚ח״׏גغحؿ؋؟؎ؤ׾剑㼭⻉דֹ׷
    ˖ 歗⫷ؿ؋؎ٕךر؝٦سծؒٝ؝٦سחכ垥彊涸ז$ٓ؎ـٓٔ׾欽ְ׷

    MJCKQFHUVSCPծMJCQOHծHJJCזו
    ˖ 葿瑞꟦ך㢌䳔ծؔ٦غ٦ٖ؎さ䧭כأٍؗٝٓ؎ٝ׀החתה׭ג遤ֲ

    1MBO،إٝـٔ׾欽ְג4*.%剑黝⻉
    ˖ *NBHF'MVYך椚䟝ـٓؐؠָ邌爙דֹ׷歗⫷כׅץג㢌䳔דֹ׷

    垥彊鋉呓ה׃ג姻׃ֻג׮ـٓؐؠכ姻׃ֻ䪔׻זְֿהָ֮׷

    㸣Ⰻח㠨׸׋歗⫷ד׮ـٓؐؠכז׿ַ姻׃ֻ邌爙׃ג׃תֲֿהָ֮׷
    ˖ ؕٓ٦فٗؿ؋؎ٕזו歗⫷ر٦ة⟃㢩׮䪔ֲֿהָדֹ׷

    View full-size slide

  28. ؕٓ٦فٗؿ؋؎ٕך䪔ְ
    ˖ +1&(ծ1/(ծ8FC1חכ*$$䕎䒭ךؕٓ٦فٗؿ؋؎ٕ׾㙵׭鴥׬ֿהָדֹ׷
    ˖ -JUUMF$.4׾ⵃ欽׃גؕٓ٦فٗؿ؋؎ٕ׾欽ְ׋葿瑞꟦ך㢌䳔׾㹋植
    ˖ (PךJNBHFחろת׸גְ׷ر؝٦تծؒٝ؝٦تכؕٓ٦فٗؿ؋؎ٕ׾؟ه٦
    ز׃גְזְ
    ˖ JNBHFKQFHװJNBHFQOHד*$$ךغ؎شָٔ《䖤דֹ׷״ֲח׃גֶֻה葺ְַ
    ׮

    View full-size slide

  29. תה׭
    ˖ *NBHF'MVYך歗⫷㢌䳔Ⳣ椚כ(Pד剅ַ׸גְ׷
    ˖ 歗⫷Ⳣ椚荈⡤כ׌ְ׋ְ$ד㹋鄲ׁ׸גְ׷
    ˖ ぐٓ؎ـٓٔך؎ٝة٦ؿؑ٦أ׾(Pד㹋鄲ׅ׷ֿהד笺뜧ח㹋鄲דֹ׷
    ˖ JP3FBEFSהJP8SJUFS׾؎ٝة٦ؿؑ٦أה׃ג⢪׏גֶֻה)551האז־׋׶
    ؿ؋؎ٕה籬־׋׶דֹג⤑ⵃ

    View full-size slide