1 Star 1 Fork 0

呜啦啦呜啦啦 / CloudStorage

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
Clone or Download
Local.go 6.71 KB
Copy Edit Raw Blame History
呜啦啦呜啦啦 authored 2021-05-30 18:22 . 2
// @File : local.go
// @Author: JunLong.Liao&此处不应有BUG!
// @Date : 2021/5/26
// @slogan: 又是不想写代码的一天,神兽保佑,代码无BUG!
// ┏┓ ┏┓
// ┏┛┻━━━━━━┛┻┓
// ┃ ღ ┃
// ┃ ┳┛ ┗┳ ┃
// ┃ ┻ ┃
// ┗━┓ ┏━┛
// ┃ ┗━━━┓
// ┃ 神兽咆哮! ┣┓
// ┃ ┏┛
// ┗┓┓┏━━━┳┓┏┛
// ┃┫┫ ┃┫┫
// ┗┻┛ ┗┻┛
package CloudStorage
import (
"errors"
"github.com/nfnt/resize"
"golang.org/x/image/bmp"
"image"
"image/gif"
"image/jpeg"
"image/png"
"io"
"log"
"mime/multipart"
"os"
"path"
"strings"
"time"
)
type Local struct {
Path string `mapstructure:"path" json:"path" yaml:"path"` // 本地文件路径
}
// 本地上传
type LocalOSS interface {
UploadFile(file *multipart.FileHeader) (path, filename string, err error)
DeleteFile(key string) error
ClipFile(filename string, wi, hi, x0, y0, x1, y1, quality int) (Path, FileName string, err error)
}
// 实例本地上传
func NewLocalOSS(c *Local) LocalOSS {
return &Local{
Path: c.Path,
}
}
// @author: [wulala](https://github.com/water-gulugulu)
// @object: *LocalUpload
// @function: UploadFile
// @description: 上传文件
// @param: file *multipart.FileHeader
// @return: Path string
// @return: FileName string
// @return: err error
func (l *Local) UploadFile(file *multipart.FileHeader) (Path, FileName string, err error) {
// 读取文件后缀
ext := path.Ext(file.Filename)
// 读取文件名并加密
name := strings.TrimSuffix(file.Filename, ext)
name = MD5V([]byte(name))
// 拼接新文件名
filename := name + "_" + time.Now().Format("20060102150405") + ext
// 尝试创建此路径
mkdirErr := os.MkdirAll(l.Path, os.ModePerm)
if mkdirErr != nil {
return "", "", errors.New("function os.MkdirAll() Filed, err:" + mkdirErr.Error())
}
// 拼接路径和文件名
p := l.Path + "/" + filename
f, openError := file.Open() // 读取文件
if openError != nil {
return "", "", errors.New("function file.Open() Filed, err:" + openError.Error())
}
out, createErr := os.Create(p)
if createErr != nil {
return "", "", errors.New("function os.Create() Filed, err:" + createErr.Error())
}
defer func() {
_ = f.Close()
_ = out.Close()
}()
_, copyErr := io.Copy(out, f) // 传输(拷贝)文件
if copyErr != nil {
return "", "", errors.New("function io.Copy() Filed, err:" + copyErr.Error())
}
return p, filename, nil
}
// @author: [wulala](https://github.com/water-gulugulu)
// @object: *LocalUpload
// @function: DeleteFile
// @description: 删除文件
// @param: key string
// @return: error
func (l *Local) DeleteFile(key string) error {
p := l.Path + "/" + key
if strings.Contains(p, l.Path) {
if err := os.Remove(p); err != nil {
return errors.New("本地文件删除失败, err:" + err.Error())
}
}
return nil
}
// @author: [wulala](https://github.com/water-gulugulu)
// @author: [wulala](https://gitee.com/diunigedaxigua)
// @function: ClipFile
// @description: 图片裁剪
// @param: filename string 要裁剪的文件名,会和Local.Path拼接组成文件名
// @param: wi int 裁剪宽度,传0则默认裁剪宽度 如原图宽为100px x0:10 x1:90 那么成图宽为x1-x0=80px
// @param: hi int 裁剪高度,传0则默认裁剪高度 如原图高为100px y0:10 y1:90 那么成图高为y1-y0=80px
// @param: x0 int 裁剪宽坐标,从多少像素开始裁剪,如原图100px x0:10那么从10像素开始裁剪
// @param: y0 int 裁剪高坐标,从多少像素开始裁剪,如原图100px y0:10那么从10像素开始裁剪
// @param: x1 int 裁剪宽坐标,从x0开始到x1像素裁剪结束,如原图100px x0:10,x1:30那么从10像素开始裁剪到40像素结束
// @param: y1 int 裁剪高坐标,从y0开始到y1像素裁剪结束,如原图100px y0:10,y1:30那么从10像素开始裁剪到40像素结束
// @param: quality int 像素精度 百分比
// @return: Path string 文件访问路径(带文件名)
// @return: FileName string 文件名
// @return: err error 错误信息
func (l *Local) ClipFile(filename string, wi, hi, x0, y0, x1, y1, quality int) (Path, FileName string, err error) {
var in, out *os.File
// 打开文件
in, err = os.Open(l.Path + "/" + filename)
if err != nil {
log.Println(err)
return
}
// 替换文件名加上_small
FileName = strings.Replace(filename, ".", "_small.", 1)
Path = l.Path + "/" + FileName
out, err = os.Create(Path)
defer func() {
_ = in.Close()
_ = out.Close()
if r := recover(); r != nil {
log.Println(r)
}
}()
var origin, canvas image.Image
var fm string
origin, fm, err = image.Decode(in)
if err != nil {
log.Println(err)
return
}
// 如果未设置宽高那么就默认截取后宽高,如果设置了宽高,那么计算最后截取剩下的宽高
if wi == 0 || hi == 0 {
wi = origin.Bounds().Max.X
hi = origin.Bounds().Max.Y
} else {
x1 += wi // x1 加上最后要截取的宽度
y1 += hi // y1 加上最后要截取的高度
// 如果大于原图宽度 那么就设置最大为原图宽度
if x1 > origin.Bounds().Max.X {
x1 = origin.Bounds().Max.X
}
// 如果大于原图高度 那么就设置最大为原图高度
if y1 > origin.Bounds().Max.Y {
y1 = origin.Bounds().Max.Y
}
}
canvas = origin
if quality == 0 {
quality = 100
}
// 图片处理
switch fm {
case "jpeg":
img := canvas.(*image.YCbCr)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.YCbCr)
subImg2 := resize.Thumbnail(uint(wi), uint(hi), subImg, resize.Lanczos3)
err = jpeg.Encode(out, subImg2, &jpeg.Options{quality})
return
case "png":
switch canvas.(type) {
case *image.NRGBA:
img := canvas.(*image.NRGBA)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.NRGBA)
subImg2 := resize.Thumbnail(uint(wi), uint(hi), subImg, resize.Lanczos3)
err = png.Encode(out, subImg2)
return
case *image.RGBA:
img := canvas.(*image.RGBA)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)
subImg2 := resize.Thumbnail(uint(wi), uint(hi), subImg, resize.Lanczos3)
err = png.Encode(out, subImg2)
return
}
case "gif":
img := canvas.(*image.Paletted)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.Paletted)
subImg2 := resize.Thumbnail(uint(wi), uint(hi), subImg, resize.Lanczos3)
err = gif.Encode(out, subImg2, &gif.Options{})
return
case "bmp":
img := canvas.(*image.RGBA)
subImg := img.SubImage(image.Rect(x0, y0, x1, y1)).(*image.RGBA)
subImg2 := resize.Thumbnail(uint(wi), uint(hi), subImg, resize.Lanczos3)
err = bmp.Encode(out, subImg2)
return
default:
err = errors.New("ERROR FORMAT")
return
}
return
}
1
https://gitee.com/diunigedaxigua/cloud-storage.git
git@gitee.com:diunigedaxigua/cloud-storage.git
diunigedaxigua
cloud-storage
CloudStorage
v0.0.1

Search