github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/tpl/images/images.go (about) 1 // Copyright 2019 The Hugo Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 // Package images provides template functions for manipulating images. 15 package images 16 17 import ( 18 "image" 19 "sync" 20 21 "github.com/pkg/errors" 22 23 "github.com/gohugoio/hugo/resources/images" 24 "github.com/gohugoio/hugo/resources/resource" 25 26 // Importing image codecs for image.DecodeConfig 27 _ "image/gif" 28 _ "image/jpeg" 29 _ "image/png" 30 31 // Import webp codec 32 _ "golang.org/x/image/webp" 33 34 "github.com/gohugoio/hugo/deps" 35 "github.com/spf13/cast" 36 ) 37 38 // New returns a new instance of the images-namespaced template functions. 39 func New(deps *deps.Deps) *Namespace { 40 return &Namespace{ 41 Filters: &images.Filters{}, 42 cache: map[string]image.Config{}, 43 deps: deps, 44 } 45 } 46 47 // Namespace provides template functions for the "images" namespace. 48 type Namespace struct { 49 *images.Filters 50 cacheMu sync.RWMutex 51 cache map[string]image.Config 52 53 deps *deps.Deps 54 } 55 56 // Config returns the image.Config for the specified path relative to the 57 // working directory. 58 func (ns *Namespace) Config(path interface{}) (image.Config, error) { 59 filename, err := cast.ToStringE(path) 60 if err != nil { 61 return image.Config{}, err 62 } 63 64 if filename == "" { 65 return image.Config{}, errors.New("config needs a filename") 66 } 67 68 // Check cache for image config. 69 ns.cacheMu.RLock() 70 config, ok := ns.cache[filename] 71 ns.cacheMu.RUnlock() 72 73 if ok { 74 return config, nil 75 } 76 77 f, err := ns.deps.Fs.WorkingDir.Open(filename) 78 if err != nil { 79 return image.Config{}, err 80 } 81 defer f.Close() 82 83 config, _, err = image.DecodeConfig(f) 84 if err != nil { 85 return config, err 86 } 87 88 ns.cacheMu.Lock() 89 ns.cache[filename] = config 90 ns.cacheMu.Unlock() 91 92 return config, nil 93 } 94 95 func (ns *Namespace) Filter(args ...interface{}) (resource.Image, error) { 96 if len(args) < 2 { 97 return nil, errors.New("must provide an image and one or more filters") 98 } 99 100 img := args[len(args)-1].(resource.Image) 101 filtersv := args[:len(args)-1] 102 103 return img.Filter(filtersv...) 104 }