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 }
func (be *Backend) GenerateThumbnail(bin string, filename string, width int, height int, crop bool) error { f, err := be.GetFileMetaData(bin, filename) if err != nil { return err } if strings.Split(f.MIME, "/")[0] != "image" { return errors.New("Batch job skipped: " + filename + " is not an image") } fpath := filepath.Join(be.filedir, bin, filename) cachedir := filepath.Join(be.filedir, bin, ".cache") if !isDir(cachedir) { if err := os.Mkdir(cachedir, 0700); err != nil { return err } } dst := filepath.Join(cachedir, strconv.Itoa(width)+"x"+strconv.Itoa(height)+"-"+filename) // Optimize to skip thumbnail generation if the thumbnail file exists // and is newer than the file. fi, err := os.Lstat(dst) if err == nil { if f.CreatedAt.After(fi.ModTime()) { // File newer than thumbnail. Ok to generate. } else { // File older than thumbnail. No need to generate. return nil } } s, err := imaging.Open(fpath) if err != nil { return err } if crop { im := imaging.Fill(s, width, height, imaging.Center, imaging.Lanczos) err = imaging.Save(im, dst) } else { im := imaging.Resize(s, width, height, imaging.Lanczos) err = imaging.Save(im, dst) } f.Links = be.GenerateLinks(f.Bin, f.Filename) be.Lock() defer be.Unlock() id := bin + filename delete(be.files, id) be.files[id] = f return err }
func (f *File) GenerateThumbnail() error { fpath := filepath.Join(f.TagDir, f.Filename) s, err := imaging.Open(fpath) if err != nil { return err } thumb := imaging.Fill(s, 75, 75, imaging.Center, imaging.NearestNeighbor) err = imaging.Save(thumb, f.ThumbnailPath()) return err }
func Resize(src io.Reader, c *CacheContext) (io.Reader, error) { raw, err := ioutil.ReadAll(src) if err != nil { return nil, err } width := c.Width data := bytes.NewReader(raw) img, format, err := image.Decode(data) if err != nil { return nil, err } var resizedImage image.NRGBA if c.Crop { minDimension := int(math.Min(float64(img.Bounds().Size().X), float64(img.Bounds().Size().Y))) if minDimension < c.Width || c.Width == 0 { width = minDimension } resizedImage = *imaging.Fill(img, width, width, imaging.Center, imaging.Lanczos) } else { resizedImage = *imaging.Resize(img, width, 0, imaging.Lanczos) } buf := new(bytes.Buffer) var imgFormat imaging.Format switch format { case "png": imgFormat = imaging.PNG case "jpeg": imgFormat = imaging.JPEG case "tiff": imgFormat = imaging.TIFF case "bmp": imgFormat = imaging.BMP default: return nil, errors.New("unsupported image format") } err = imaging.Encode(buf, resizedImage.SubImage(resizedImage.Rect), imgFormat) if err != nil { return nil, err } return buf, err }
func (f *File) GenerateImage(width int, height int, crop bool) error { fpath := filepath.Join(f.TagDir, f.Filename) s, err := imaging.Open(fpath) if err != nil { return err } if crop { im := imaging.Fill(s, width, height, imaging.Center, imaging.Lanczos) err = imaging.Save(im, f.ImagePath(width, height)) } else { im := imaging.Resize(s, width, height, imaging.Lanczos) err = imaging.Save(im, f.ImagePath(width, height)) } return err }
func main() { flag.Parse() args := flag.Args() file := "cat15.jpg" if len(args) >= 1 { file = args[0] } reader, err := os.Open(file) if err != nil { panic(err) } var batch uint32 = 1 img, _, _ := image.Decode(reader) img = imaging.Fill(img, 224, 224, imaging.Center, imaging.Lanczos) /* test, _ := os.OpenFile("test.jpg", os.O_CREATE|os.O_WRONLY, 0644) jpeg.Encode(test, img, nil) */ symbol, err := ioutil.ReadFile("./Inception-symbol.json") if err != nil { panic(err) } params, err := ioutil.ReadFile("./Inception-0009.params") if err != nil { panic(err) } synset, err := os.Open("./synset.txt") if err != nil { panic(err) } pred, err := gomxnet.NewPredictor(gomxnet.Model{symbol, params}, gomxnet.Device{gomxnet.CPU, 0}, []gomxnet.InputNode{{"data", []uint32{batch, 3, 224, 224}}}) if err != nil { panic(err) } input, _ := gomxnet.InputFrom([]image.Image{img}, gomxnet.ImageMean{117.0, 117.0, 117.0}) pred.Forward("data", input) output, _ := pred.GetOutput(0) pred.Free() dict := []string{} scanner := bufio.NewScanner(synset) for scanner.Scan() { dict = append(dict, scanner.Text()) } outputLen := uint32(len(output)) / batch var b uint32 = 0 for ; b < batch; b++ { out := output[b*outputLen : (b+1)*outputLen] index := make([]int, len(out)) gomxnet.Argsort(out, index) fmt.Printf("image #%d\n", b) for i := 0; i < 20; i++ { fmt.Printf("%d: %f, %d, %s\n", i, out[i], index[i], dict[index[i]]) } fmt.Println("") } }
func handleServeImage(ctx context.Context, w http.ResponseWriter, r *http.Request) { img, err := ImageByID(sq.DB(ctx), web.Args(ctx).ByIndex(0)) switch err { case nil: // all good case sq.ErrNotFound: web.StdJSONResp(w, http.StatusNotFound) return default: log.Error("cannot get object", "object", web.Args(ctx).ByIndex(0), "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } if web.CheckLastModified(w, r, img.Created) { return } fs := FileStore(ctx) fd, err := fs.Read(img.Created.Year(), img.ImageID) if err != nil { log.Error("cannot read image file", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } defer fd.Close() w.Header().Set("X-Image-ID", img.ImageID) w.Header().Set("X-Image-Width", fmt.Sprint(img.Width)) w.Header().Set("X-Image-Height", fmt.Sprint(img.Height)) w.Header().Set("X-Image-Created", img.Created.Format(time.RFC3339)) w.Header().Set("Content-Type", "image/jpeg") if r.URL.Query().Get("resize") == "" { io.Copy(w, fd) return } image, err := jpeg.Decode(fd) if err != nil { log.Error("cannot read image file", "image", img.ImageID, "error", err.Error()) web.StdJSONResp(w, http.StatusInternalServerError) return } var width, height int if _, err := fmt.Sscanf(r.URL.Query().Get("resize"), "%dx%d", &width, &height); err != nil { log.Error("cannot resize image", "image", img.ImageID, "error", err.Error()) } else { switch img.Orientation { case 1: // all good case 3: image = imaging.Rotate180(image) case 8: image = imaging.Rotate90(image) case 6: image = imaging.Rotate270(image) default: log.Debug("unknown image orientation", "decoder", "EXIF", "image", img.ImageID, "value", fmt.Sprint(img.Orientation)) } image = imaging.Fill(image, width, height, imaging.Center, imaging.Linear) } imaging.Encode(w, image, imaging.JPEG) }
// CreateThumnail builds a JPG thumbnail and can rotate if an exif bit is set. func CreateThumbnail(deps dependencies.Dependencies, r io.ReadSeeker) (string, int, error) { raw, format, err := image.Decode(r) if format == "" { return "", 0, nil } if format == "jpeg" || format == "jpg" { deps.Debug("Received JPG") orientation, err := readOrientation(r) if err == nil { deps.Debug("Rotating JPG", "orientation", orientation) raw = rotate(raw, orientation) } } deps.Debug("Thumbnail format", "fmt", format) if err != nil { deps.Error("Failed to decode image") return "", 0, err } fs := deps.Fs tmpFilePath := lib.TempFilePath("thumbnail") tmpFile, err := fs.Create(tmpFilePath) if err != nil { deps.Error("Failed to create temp file", "path", tmpFilePath) return "", 0, err } // Make sure we close. closeTmpFile := func() { if tmpFile != nil { tmpFile.Close() tmpFile = nil } } defer closeTmpFile() h := sha1.New() var wc writeCounter mw := io.MultiWriter(tmpFile, h, wc) // Generate Thumbnail image data dst := imaging.Fill(raw, 200, 200, imaging.Center, imaging.Lanczos) // Write it err = imaging.Encode(mw, dst, imaging.JPEG) if err != nil { deps.Error("Failed to encode data") return "", 0, err } hash := fmt.Sprintf("%x", h.Sum(nil)) deps.Debug("Thumbnail hash", "hash:", hash) newPath := lib.LocalPath(hash) // Move temp thumbnail to final destination. err = os.Rename(tmpFilePath, newPath) if err != nil { deps.Error("Failed to rename file") // Todo delete file return hash, int(wc), err } // Set permissons err = fs.Chmod(newPath, 0644) if err != nil { deps.Error("Failed to set permissions", "path", newPath) // Todo delete file return hash, int(wc), err } return hash, int(wc), nil }