func ProcessPhoto(photo *Photo) error { origImg, err := imaging.Open(GetPhotoPath(photo, "o")) if err != nil { return err } src := imaging.Clone(origImg) for _, sz := range PhotoSizes { var dst image.Image switch sz.Type { case "thumbnail": dst = imaging.Thumbnail(src, sz.Width, sz.Height, imaging.Lanczos) case "fit": dst = imaging.Fit(src, sz.Width, sz.Height, imaging.Lanczos) } err := imaging.Save(dst, GetPhotoPath(photo, sz.Suffix)) if err != nil { return err } } return nil }
func ProcessAvatar(user *User) error { origImg, err := imaging.Open(GetAvatarPath(user, "o")) if err != nil { return err } src := imaging.Clone(origImg) for _, sz := range AvatarSizes { var dst image.Image switch sz.Type { case "thumbnail": dst = imaging.Thumbnail(src, sz.Width, sz.Height, imaging.Lanczos) case "fit": dst = imaging.Fit(src, sz.Width, sz.Height, imaging.Lanczos) } err := imaging.Save(dst, GetAvatarPath(user, sz.Suffix)) if err != nil { return err } } return nil }
func (api *Api) Resize(imgloc string, xsize, ysize int, resizeType string) bool { dest := setSize(imgloc, xsize, ysize) if _, err := os.Stat(dest); err == nil { return true } bts, err := ioutil.ReadFile(imgloc) if err != nil { fmt.Println(err) return false } rdr := bytes.NewReader(bts) i, _, err := image.Decode(rdr) if err != nil { fmt.Println(err) return false } var fsimg *image.NRGBA switch resizeType { case "fit": fsimg = imaging.Fit(i, xsize, ysize, imaging.Lanczos) case "thumb": fsimg = imaging.Thumbnail(i, xsize, ysize, imaging.Lanczos) default: fsimg = imaging.Resize(i, xsize, ysize, imaging.Lanczos) } out, err := os.Create(dest) if err != nil { return false } defer out.Close() jpeg.Encode(out, fsimg, nil) return true }
func (h *ImgHandler) processImage(in io.Reader, out io.Writer, mode string, width int, height int) error { if Config.Image.UseGoRoutine { ImageChannel <- 1 defer func() { <-ImageChannel }() } img, _, err := image.Decode(in) if err != nil { glog.Fatal(err) return err } var m *image.NRGBA switch mode { case "z": m = imaging.Fit(img, width, height, imaging.Lanczos) case "x": m = imaging.Fill(img, width, height, imaging.Center, imaging.Lanczos) } jpeg.Encode(out, m, &jpeg.Options{Config.Image.ReadQuality}) return nil }
// Extracts cover func (c *Convertor) ExtractCover(file string, info os.FileInfo) { c.CurrFile += 1 cover, err := c.GetCoverImage(file, info) if err != nil { fmt.Fprintf(os.Stderr, "Error GetCoverImage: %v\n", err.Error()) return } if c.Opts.Width > 0 || c.Opts.Height > 0 { if c.Opts.Fit { cover = imaging.Fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } else { cover = imaging.Resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } } filename := filepath.Join(c.Opts.Outdir, fmt.Sprintf("%s.jpg", c.getBasename(file))) f, err := os.Create(filename) if err != nil { fmt.Fprintf(os.Stderr, "Error Create: %v\n", err.Error()) return } defer f.Close() jpeg.Encode(f, cover, &jpeg.Options{c.Opts.Quality}) }
// transformImage modifies the image m based on the transformations specified // in opt. func transformImage(m image.Image, opt Options) image.Image { // resize if needed if w, h, resize := resizeParams(m, opt); resize { if opt.Fit { m = imaging.Fit(m, w, h, resampleFilter) } else { if w == 0 || h == 0 { m = imaging.Resize(m, w, h, resampleFilter) } else { m = imaging.Thumbnail(m, w, h, resampleFilter) } } } // flip if opt.FlipVertical { m = imaging.FlipV(m) } if opt.FlipHorizontal { m = imaging.FlipH(m) } // rotate switch opt.Rotate { case 90: m = imaging.Rotate90(m) case 180: m = imaging.Rotate180(m) case 270: m = imaging.Rotate270(m) } return m }
// Extracts thumbnail func (c *Convertor) ExtractThumbnail(file string, info os.FileInfo) { c.CurrFile += 1 cover, err := c.GetCoverImage(file, info) if err != nil { fmt.Fprintf(os.Stderr, "Error GetCoverImage: %v\n", err.Error()) return } if err != nil { fmt.Fprintf(os.Stderr, "Error Thumbnail: %v\n", err.Error()) return } if c.Opts.Width > 0 || c.Opts.Height > 0 { if c.Opts.Fit { cover = imaging.Fit(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } else { cover = imaging.Resize(cover, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } } else { cover = imaging.Resize(cover, 256, 0, filters[c.Opts.Filter]) } imagick.Initialize() mw := imagick.NewMagickWand() defer mw.Destroy() b := new(bytes.Buffer) png.Encode(b, cover) err = mw.ReadImageBlob(b.Bytes()) if err != nil { fmt.Fprintf(os.Stderr, "Error ReadImageBlob: %v\n", err.Error()) } var fileuri string var filename string if c.Opts.Outfile == "" { fileuri = "file://" + file filename = filepath.Join(c.Opts.Outdir, fmt.Sprintf("%x.png", md5.Sum([]byte(fileuri)))) } else { abs, _ := filepath.Abs(c.Opts.Outfile) fileuri = "file://" + abs filename = abs } mw.SetImageFormat("PNG") mw.SetImageProperty("Software", "CBconvert") mw.SetImageProperty("Description", "Thumbnail of "+fileuri) mw.SetImageProperty("Thumb::URI", fileuri) mw.SetImageProperty("Thumb::MTime", strconv.FormatInt(info.ModTime().Unix(), 10)) mw.SetImageProperty("Thumb::Size", strconv.FormatInt(info.Size(), 10)) mw.SetImageProperty("Thumb::Mimetype", mime.TypeByExtension(filepath.Ext(file))) mw.WriteImage(filename) }
func resizeEmoji(img image.Image, width int, height int) image.Image { emojiWidth := float64(width) emojiHeight := float64(height) var emoji image.Image if emojiHeight <= MaxEmojiHeight && emojiWidth <= MaxEmojiWidth { emoji = img } else { emoji = imaging.Fit(img, MaxEmojiWidth, MaxEmojiHeight, imaging.Lanczos) } return emoji }
func MakeFromImage(srcImage image.Image, t string, w, h int) (image *image.NRGBA, err error) { switch t { case "thumbnail": image = imaging.Thumbnail(srcImage, w, h, imaging.Lanczos) case "resize": image = imaging.Resize(srcImage, w, h, imaging.Lanczos) case "fit": image = imaging.Fit(srcImage, w, h, imaging.Lanczos) default: image = imaging.Thumbnail(srcImage, w, h, imaging.Lanczos) } return image, nil }
func getImage(filename string, small bool) (io.ReadCloser, error) { if !small { return os.Open(filename) } fullImage, err := imaging.Open(filename) if err != nil { return nil, err } resized := imaging.Fit(fullImage, config.SmallRes, config.SmallRes, imaging.Linear) r, w := io.Pipe() go imaging.Encode(w, resized, imaging.JPEG) return r, nil }
func MakeFromReader(reader io.Reader, t string, w, h int) (image *image.NRGBA, err error) { srcImage, err := Open(reader) if err != nil { return nil, err } switch t { case "thumbnail": image = imaging.Thumbnail(srcImage, w, h, imaging.Lanczos) case "resize": image = imaging.Resize(srcImage, w, h, imaging.Lanczos) case "fit": image = imaging.Fit(srcImage, w, h, imaging.Lanczos) default: image = imaging.Thumbnail(srcImage, w, h, imaging.Lanczos) } return }
// Transforms image (resize, rotate, flip, brightness, contrast) func (c *Convertor) TransformImage(img image.Image) image.Image { var i image.Image = img if c.Opts.Width > 0 || c.Opts.Height > 0 { if c.Opts.Fit { i = imaging.Fit(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } else { i = imaging.Resize(i, c.Opts.Width, c.Opts.Height, filters[c.Opts.Filter]) } } if c.Opts.Rotate > 0 { switch c.Opts.Rotate { case 90: i = imaging.Rotate90(i) case 180: i = imaging.Rotate180(i) case 270: i = imaging.Rotate270(i) } } if c.Opts.Flip != "none" { switch c.Opts.Flip { case "horizontal": i = imaging.FlipH(i) case "vertical": i = imaging.FlipV(i) } } if c.Opts.Brightness != 0 { i = imaging.AdjustBrightness(i, c.Opts.Brightness) } if c.Opts.Contrast != 0 { i = imaging.AdjustContrast(i, c.Opts.Contrast) } return i }
// Create HD and Thumbs Photos func CreatePhotos(a *model.Album, p *model.Photo) (err error) { src, err := imaging.Open(a.PathSource() + p.OriginalName) if err != nil { return err } var dst *image.NRGBA filename := a.PathHD() + p.Filename log.Printf("Saving HD: %s\n", filename) dst = imaging.Fit(src, cfg.Image.MaxWidth, cfg.Image.MaxHeight, imaging.Lanczos) size, err := rewriteImage(dst, filename) if err != nil { return err } p.FileSizeHD = size filename = a.PathThumbs() + p.Filename log.Printf("Saving Thumb: %s\n", filename) dst = imaging.Thumbnail(dst, cfg.Image.ThumbWidth, cfg.Image.ThumbHeight, imaging.CatmullRom) // resize and crop the image to make a 200x200 thumbnail _, err = rewriteImage(dst, filename) return err }
func do_params(ctx *context, ctrl *ext.Controller) bool { qr := ctrl.Request.Param("qrcode") if qr != "" { if size, err := strconv.ParseInt(qr, 10, 64); err == nil { return do_qrcode(ctx, ctrl, int(size)) } } resize := ctrl.Request.Param("resize") if resize != "" { fn := path.Join(ctx.app.Options.StaticRoot, "resize", util.ResizeKey(ctrl.Request.URI(), resize)) if util.Exist(fn) { ctrl.File(fn) return true } if rect, err := util.ParseRect(resize, "x"); err == nil { f1 := path.Join(ctx.app.Options.StaticRoot, ctrl.Request.URI()) ctx.Info("f1 :%s", f1) if src, err := imaging.Open(f1); err == nil { dst := imaging.Resize(src, rect.Width, rect.Height, imaging.Lanczos) if err := imaging.Save(dst, fn); err == nil { ctrl.File(fn) return true } } } } fit := ctrl.Request.Param("fit") if fit != "" { fn := path.Join(ctx.app.Options.StaticRoot, "fit", util.ResizeKey(ctrl.Request.URI(), resize)) if util.Exist(fn) { ctrl.File(fn) return true } if rect, err := util.ParseRect(resize, "x"); err == nil { f1 := path.Join(ctx.app.Options.StaticRoot, ctrl.Request.URI()) if src, err := imaging.Open(f1); err == nil { dst := imaging.Fit(src, rect.Width, rect.Height, imaging.Lanczos) if err := imaging.Save(dst, fn); err == nil { ctrl.File(fn) return true } } } } thumbnail := ctrl.Request.Param("thumbnail") if thumbnail != "" { fn := path.Join(ctx.app.Options.StaticRoot, "thumbnail", util.ResizeKey(ctrl.Request.URI(), resize)) if util.Exist(fn) { ctrl.File(fn) return true } if rect, err := util.ParseRect(thumbnail, "x"); err == nil { f1 := path.Join(ctx.app.Options.StaticRoot, ctrl.Request.URI()) if src, err := imaging.Open(f1); err == nil { dst := imaging.Thumbnail(src, rect.Width, rect.Height, imaging.Lanczos) if err := imaging.Save(dst, fn); err == nil { ctrl.File(fn) return true } } } } return false }
func (p *program) downloadWriteKey(key string, w http.ResponseWriter) error { bl, found := downloadMapper[key] if !found { http.Error(w, "Not found", 404) return nil } w.Header().Set("Content-Disposition", `attachment; filename="photos.tar"`) tw := tar.NewWriter(w) result := &bytes.Buffer{} for _, item := range bl.list { filename := filepath.Join(config.FileRoot, bl.folder, item) fi, err := os.Stat(filename) if err != nil { return err } if !bl.small { header, err := tar.FileInfoHeader(fi, "") if err != nil { return err } err = tw.WriteHeader(header) if err != nil { return err } f, err := os.Open(filename) if err != nil { return err } _, err = io.Copy(tw, f) f.Close() if err != nil { return err } } else { fullImage, err := imaging.Open(filename) if err != nil { return err } resized := imaging.Fit(fullImage, config.SmallRes, config.SmallRes, imaging.Linear) err = imaging.Encode(result, resized, imaging.JPEG) if err != nil { return err } header := &tar.Header{ Name: item, Size: int64(result.Len()), Mode: 0666, ModTime: fi.ModTime(), } err = tw.WriteHeader(header) if err != nil { return err } _, err = io.Copy(tw, result) if err != nil { return err } result.Reset() } } return tw.Close() }
// transformImage modifies the image m based on the transformations specified // in opt. func transformImage(m image.Image, opt Options) image.Image { // convert percentage width and height values to absolute values imgW := m.Bounds().Max.X - m.Bounds().Min.X imgH := m.Bounds().Max.Y - m.Bounds().Min.Y var w, h int if 0 < opt.Width && opt.Width < 1 { w = int(float64(imgW) * opt.Width) } else if opt.Width < 0 { w = 0 } else { w = int(opt.Width) } if 0 < opt.Height && opt.Height < 1 { h = int(float64(imgH) * opt.Height) } else if opt.Height < 0 { h = 0 } else { h = int(opt.Height) } // never resize larger than the original image if !opt.ScaleUp { if w > imgW { w = imgW } if h > imgH { h = imgH } } // resize if w != 0 || h != 0 { if opt.Fit { m = imaging.Fit(m, w, h, resampleFilter) } else { if w == 0 || h == 0 { m = imaging.Resize(m, w, h, resampleFilter) } else { m = imaging.Thumbnail(m, w, h, resampleFilter) } } } // flip if opt.FlipVertical { m = imaging.FlipV(m) } if opt.FlipHorizontal { m = imaging.FlipH(m) } // rotate switch opt.Rotate { case 90: m = imaging.Rotate90(m) case 180: m = imaging.Rotate180(m) case 270: m = imaging.Rotate270(m) } return m }
func getItemThumbnail(s *Service, i *Item, size int) (io.ReadSeeker, string, error) { key := fmt.Sprintf("thumb-%s-%d", i.Hash, size) fn := func() (interface{}, error) { //first check cache. if cached, err := s.cache.Get(key); err == nil { return &readSeekerMimeType{read: cached}, nil } //massive short cut here. if we have a "large" thumb then just resize that... if size < THUMBNAIL_LARGE { //check cache for LARGE key := fmt.Sprintf("thumb-%s-%d", i.Hash, THUMBNAIL_LARGE) if cached, err := s.cache.Get(key); err == nil { //resize this. if img, _, err := image.Decode(cached); err != nil { img = imaging.Fit(img, size, size, imaging.Box) var wr bytes.Buffer if err := jpeg.Encode(&wr, img, nil); err != nil { r := bytes.NewReader(wr.Bytes()) s.cache.SetReader(key, r) return &readSeekerMimeType{read: r, mime: "image/jpeg"}, nil } } } } //no cache, create file. rsc, err := s.store.Get(i.Hash) if err != nil { return nil, err } defer rsc.Close() var r io.ReadSeeker var m string //to get the type factory that may be capable of creating a thumbnail we use //the typeMap f := InspecterFor(i) var ok bool var tmb Thumbnailer if f != nil { tmb, ok = f.(Thumbnailer) } if ok { if err = f.EnsureMeta(i); err == nil { //ensure we don't try to make too many at once... //before we block on putting a token into the bucket. if the bucket is full this will block. //after we take a token out of the bucket, so another can process. thumbLimit <- struct{}{} r, m, err = tmb.Thumbnail(rsc, size) <-thumbLimit s.cache.SetReader(key, r) } } else { //fake it return &readSeekerMimeType{ read: bytes.NewReader(createGif(uint16(size), uint16(size))), mime: "image/gif", }, nil } if err != nil { return nil, err } return &readSeekerMimeType{read: r, mime: m}, nil } r, err := thumbGroup.Do(key, fn) if err != nil { return nil, "", err } rsmt := r.(*readSeekerMimeType) return rsmt.read, rsmt.mime, nil }
func (a *Api) Create(data []byte, name string, descr string) (Img, error) { named := true bts := bytes.NewReader(data) img, _, err := image.Decode(bts) if err != nil { return Img{}, err } tm := time.Now() if name == "" || len(name) <= int(a.nesting) { name = randName() named = false } for { found, err := a.ExistName(name) if err != nil { return Img{}, err } if found { name = randName() } if !found { break } } path := a.path for i := uint8(0); i < a.nesting; i++ { path += "/" + name[i:i+1] } os.MkdirAll(path, 0777) for _, v := range a.sizes { save_path := path + "/" + name + "_" + strconv.Itoa(v.Width) + "x" + strconv.Itoa(v.Height) save_path_with_ex := save_path + ".jpg" if v.Crop == "thumb" { c := imaging.Thumbnail(img, v.Width, v.Height, imaging.Lanczos) imaging.Save(c, save_path_with_ex) } else if v.Crop == "fit" { c := imaging.Fit(img, v.Width, v.Height, imaging.Lanczos) imaging.Save(c, save_path_with_ex) } if a.WebpAddr != "" { cmd := exec.Command(a.WebpAddr, save_path_with_ex, "-o", save_path+".webp") err := cmd.Run() if err != nil { fmt.Println(err) return Img{}, errors.New("Webp Not Working") } } } out, err := os.Create(path + "/" + name + ".jpg") if err != nil { return Img{}, err } defer out.Close() jpeg.Encode(out, img, nil) if a.WebpAddr != "" { cmd := exec.Command(a.WebpAddr, path+"/"+name+".jpg", "-o", path+"/"+name+".webp") err := cmd.Run() if err != nil { fmt.Println(err) return Img{}, errors.New("Webp Not Working") } } im := Img{ Name: name, Description: descr, Named: named, Created: tm.UnixNano(), Updated: tm.UnixNano(), } err = a.Db.Insert(&im) if err != nil { return Img{}, err } return im, nil }
func (p *program) serveFile(w http.ResponseWriter, r *http.Request, fullPath, urlPath, resolutionString string) error { if len(resolutionString) == 0 { http.ServeFile(w, r, fullPath) return nil } createThumbFrom := fullPath imgSize, err := strconv.Atoi(resolutionString) if err != nil { return err } isMovie := false cachePath := filepath.Join(p.cacheDir, r.URL.Path) if strings.HasSuffix(urlPath, ".mp4") { // Movie: avconv -i /data/store/Pictures/2015-Q1/VID_20150125_1928.mp4 -vframes 1 -ss 00:00:01 out.jpg createThumbFrom = cachePath + ".orig.jpg" cachePath = cachePath + ".jpg" isMovie = true } _, err = os.Stat(cachePath) if os.IsNotExist(err) { if isMovie { var output []byte for _, time := range movieTimes { cmd := exec.Command("avconv", "-i", fullPath, "-vframes", "1", "-ss", time, createThumbFrom) output, err = cmd.CombinedOutput() if err == nil { _, err = os.Stat(createThumbFrom) // Make sure avconv wrote file. if os.IsNotExist(err) { continue } break } } if err != nil { logger.Errorf("Problem converting thumbnail for movie: %v\n%s\n", err, output) createThumbFrom = filepath.Join(p.execDir, "template", badThumb) } } // Resize image, open cache image. cacheDir, _ := filepath.Split(cachePath) err := os.MkdirAll(cacheDir, 0777) if err != nil { return err } fullImage, err := imaging.Open(createThumbFrom) if err != nil { return err } resized := imaging.Fit(fullImage, imgSize, imgSize, imaging.Linear) // Um, assume JPG for now. cf, err := os.Create(cachePath) if err != nil { return err } err = imaging.Encode(cf, resized, imaging.JPEG) cf.Close() if err != nil { return err } } http.ServeFile(w, r, cachePath) return nil }