func CenterCrop(img *io.Reader, width, height int) ([]byte, error) {
	m, _, err := image.Decode(*img)
	if err != nil {
		return nil, err
	}

	// TODO: I probably can switch to using imaging.Thumbnail here.
	imgW := float64(m.Bounds().Max.X - m.Bounds().Min.X)
	imgH := float64(m.Bounds().Max.Y - m.Bounds().Min.Y)
	targetW := float64(width)
	targetH := float64(height)

	var scale float64

	if imgW*targetH > targetW*imgH {
		scale = targetH / imgH
	} else {
		scale = targetW / imgW
	}

	m = imaging.Resize(m, int(imgW*scale), int(imgH*scale), imaging.Lanczos)
	m = imaging.CropCenter(m, width, height)

	buf := new(bytes.Buffer)
	jpeg.Encode(buf, m, &jpeg.Options{Quality: 95})

	return buf.Bytes(), nil
}
Exemple #2
0
/* resize when there is no height constraint, otherwise crop */
func (result *imageInfo) resizeOrCrop(img image.Image, width int, height int) image.Image {
	var imgdata image.Image
	if height == 0 {
		imgdata = imaging.Resize(img, width, height, imaging.Lanczos)
	} else {
		imgdata = imaging.CropCenter(img, width, height)
	}
	result.width = imgdata.Bounds().Max.X
	result.height = imgdata.Bounds().Max.Y
	return imgdata
}
Exemple #3
0
func (m *User) ValidateAndSetAvatar(avatarFile io.Reader, filename string) error {
	var img image.Image
	var err error
	var ext string
	var tmpFile *os.File
	if tmpFile, err = ioutil.TempFile(setting.TmpPath, "uploaded-avatar-"); err != nil {
		return err
	}
	defer os.Remove(tmpFile.Name())
	defer tmpFile.Close()
	if _, err = io.Copy(tmpFile, avatarFile); err != nil {
		return err
	}
	tmpFile.Seek(0, 0)
	if filename != "" {
		ext = strings.ToLower(filepath.Ext(filename))
	} else {
		ext = utils.GetImageFormat(tmpFile)
		tmpFile.Seek(0, 0)
	}
	if ext != ".jpg" && ext != ".jpeg" && ext != ".png" && ext != ".gif" {
		return errors.New("只允许jpg, png, gif类型的图片")
	}
	switch ext {
	case ".jpg", ".jpeg":
		img, err = jpeg.Decode(tmpFile)
		if err != nil {
			return errors.New("无法识别此jpg文件")
		}
	case ".png":
		img, err = png.Decode(tmpFile)
		if err != nil {
			return errors.New("无法识别此png文件")
		}
	case ".gif":
		img, err = gif.Decode(tmpFile)
		if err != nil {
			return errors.New("无法识别此gif文件")
		}
	}

	//crop正方形
	bound := img.Bounds()
	if w, h := bound.Dx(), bound.Dy(); w > h {
		img = imaging.CropCenter(img, h, h)
	} else if w < h {
		img = imaging.CropCenter(img, w, w)
	}
	//制作缩略图
	imgL := imaging.Resize(img, 220, 220, imaging.Lanczos)
	imgM := imaging.Resize(img, 48, 48, imaging.Lanczos)
	imgS := imaging.Resize(img, 24, 24, imaging.Lanczos)
	uuid := strings.Replace(uuid.New(), "-", "", -1)
	imgLName, imgMName, imgSName := setting.TmpPath+uuid+"-l.png", setting.TmpPath+uuid+"-m.png", setting.TmpPath+uuid+"-s.png"
	errL, errM, errS := imaging.Save(imgL, imgLName), imaging.Save(imgM, imgMName), imaging.Save(imgS, imgSName)
	if errL != nil || errM != nil || errS != nil {
		return errors.New("无法保存头像临时文件")
	}
	defer os.Remove(imgLName)
	defer os.Remove(imgMName)
	defer os.Remove(imgSName)

	_, errL = setting.AvatarFSM.PutFile(imgLName, string(uuid[0])+"/"+string(uuid[1])+"/"+uuid+"-l.png")
	_, errM = setting.AvatarFSM.PutFile(imgMName, string(uuid[0])+"/"+string(uuid[1])+"/"+uuid+"-m.png")
	_, errS = setting.AvatarFSM.PutFile(imgSName, string(uuid[0])+"/"+string(uuid[1])+"/"+uuid+"-s.png")

	if errL != nil || errM != nil || errS != nil {
		return errors.New("无法保存头像")
	}
	if m.Avatar != "" {
		errL = setting.AvatarFSM.Delete(m.Avatar + "-l.png")
		errM = setting.AvatarFSM.Delete(m.Avatar + "-m.png")
		errS = setting.AvatarFSM.Delete(m.Avatar + "-s.png")
	}
	m.Avatar = uuid
	//errL, errM, errS = setting.AvatarFSM.Delete
	return nil
}