Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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

}
Beispiel #5
0
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
}
Beispiel #6
0
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("")
	}
}
Beispiel #7
0
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)
}
Beispiel #8
0
// 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
}