diff options
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/format/files.go | 10 | ||||
| -rw-r--r-- | utils/minio/minio.go | 47 | ||||
| -rw-r--r-- | utils/transformers/image.go | 54 | ||||
| -rw-r--r-- | utils/transformers/tokens.go | 13 |
4 files changed, 93 insertions, 31 deletions
diff --git a/utils/format/files.go b/utils/format/files.go index 82f1546..dcdcaf7 100644 --- a/utils/format/files.go +++ b/utils/format/files.go @@ -51,21 +51,19 @@ func DecodeImage(imgData []byte) (image.Image, string, error) { return img, formatName, err } -func GetImageFileSize(img image.Image) int64 { +func GetImageSizeAndData(img image.Image) (int64, []byte, error) { var buf bytes.Buffer switch img.(type) { case *image.NRGBA, *image.RGBA, *image.YCbCr: - // Use PNG encoding for lossless compression err := png.Encode(&buf, img) if err != nil { - return 0 + return 0, nil, err } default: - // Fallback to JPEG encoding for other formats err := jpeg.Encode(&buf, img, &jpeg.Options{Quality: 85}) if err != nil { - return 0 + return 0, nil, err } } - return int64(buf.Len()) + return int64(buf.Len()), buf.Bytes(), nil } diff --git a/utils/minio/minio.go b/utils/minio/minio.go index c5576b1..30be90e 100644 --- a/utils/minio/minio.go +++ b/utils/minio/minio.go @@ -1 +1,48 @@ package minio + +import ( + "bytes" + "context" + "fmt" + "imageboard/config" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" +) + +func UploadImage(imageData []byte, sizeType config.ImageSizeType, fileName string, contentType string) error { + ctx := context.Background() + + minioClient, err := minio.New(config.S3.Endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(config.S3.AccessKey, config.S3.SecretAccessKey, ""), + Secure: config.S3.UseSSL, + }) + if err != nil { + return fmt.Errorf("failed to initialize MinIO client: %v", err) + } + + bucketExists, err := minioClient.BucketExists(ctx, config.S3.BucketName) + if err != nil { + return fmt.Errorf("failed to check bucket existence: %v", err) + } + + if !bucketExists { + err = minioClient.MakeBucket(ctx, config.S3.BucketName, minio.MakeBucketOptions{ + Region: config.S3.Region, + }) + if err != nil { + return fmt.Errorf("failed to create bucket: %v", err) + } + } + + objectPath := fmt.Sprintf("%s/%s", sizeType, fileName) + + _, err = minioClient.PutObject(ctx, config.S3.BucketName, objectPath, bytes.NewReader(imageData), int64(len(imageData)), minio.PutObjectOptions{ + ContentType: contentType, + }) + if err != nil { + return fmt.Errorf("failed to upload image: %v", err) + } + + return nil +} diff --git a/utils/transformers/image.go b/utils/transformers/image.go index e392f7f..369b7c6 100644 --- a/utils/transformers/image.go +++ b/utils/transformers/image.go @@ -3,20 +3,21 @@ package transformers import ( "image" "imageboard/config" - "imageboard/models" "imageboard/utils/format" "imageboard/utils/validators" "strings" + + "github.com/nfnt/resize" ) -func TransformImageToVariant(img image.Image, variant config.ImageSizeType) (models.ImageSize, image.Image, error) { +func TransformImageToVariant(img image.Image, variant config.ImageSizeType) (int, int, int64, []byte, error) { variantSizeMap := map[config.ImageSizeType]int{ config.ImageSizeTypeIcon: 64, config.ImageSizeTypeThumbnail: 256, config.ImageSizeTypeSmall: 512, config.ImageSizeTypeMedium: 1024, config.ImageSizeTypeLarge: 2048, - config.ImageSizeTypeOriginal: 0, // Original size, no resizing + config.ImageSizeTypeOriginal: 0, } maxWidth := variantSizeMap[variant] @@ -24,14 +25,12 @@ func TransformImageToVariant(img image.Image, variant config.ImageSizeType) (mod img = ResizeImage(img, maxWidth) } - fileSize := format.GetImageFileSize(img) + fileSize, imageData, err := format.GetImageSizeAndData(img) + if err != nil { + return 0, 0, 0, nil, err + } - return models.ImageSize{ - SizeType: variant, - Width: img.Bounds().Dx(), - Height: img.Bounds().Dy(), - FileSize: fileSize, - }, img, nil + return img.Bounds().Dx(), img.Bounds().Dy(), fileSize, imageData, nil } func ResizeImage(img image.Image, maxWidth int) image.Image { @@ -40,19 +39,9 @@ func ResizeImage(img image.Image, maxWidth int) image.Image { } ratio := float64(maxWidth) / float64(img.Bounds().Dx()) - newWidth := int(float64(img.Bounds().Dx()) * ratio) - newHeight := int(float64(img.Bounds().Dy()) * ratio) - newImg := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight)) - for y := 0; y < newHeight; y++ { - for x := 0; x < newWidth; x++ { - srcX := int(float64(x) / ratio) - srcY := int(float64(y) / ratio) - if srcX < img.Bounds().Dx() && srcY < img.Bounds().Dy() { - newImg.Set(x, y, img.At(srcX, srcY)) - } - } - } - return newImg + newHeight := uint(float64(img.Bounds().Dy()) * ratio) + + return resize.Resize(uint(maxWidth), newHeight, img, resize.Lanczos3) } func CreateUniqueFileName(sourceURLOrOriginalName, imageFormat string) string { @@ -64,11 +53,11 @@ func CreateUniqueFileName(sourceURLOrOriginalName, imageFormat string) string { currentTime := format.GetCurrentTimeAsTimestamp() fileNameWithoutExtension := format.RemoveExtension(fileName) - fileName = GenerateTokenFromString(fileNameWithoutExtension + "_" + format.Int64ToString(currentTime)) + fileName = GenerateTokenFromString(fileNameWithoutExtension + "_" + format.Int64ToString(currentTime) + "_" + GenerateUUID()) if len(fileName) > 32 { mid := len(fileName) / 2 - fileName = fileName[mid-16 : mid+16] + fileName = fileName[:mid-16] + format.Int64ToString(currentTime) + fileName[mid+16:] } return fileName + "." + imageFormat } @@ -87,3 +76,18 @@ func ConvertStringRatingToType(rating string) (config.Rating, error) { return config.RatingSafe, nil } } + +func ConvertStringToContentType(contentType string) (config.ImageContentType, error) { + switch contentType { + case "image/jpeg": + return config.ImageContentTypeJPEG, nil + case "image/png": + return config.ImageContentTypePNG, nil + case "image/gif": + return config.ImageContentTypeGIF, nil + case "image/webp": + return config.ImageContentTypeWebP, nil + default: + return config.ImageContentTypeJPEG, nil + } +} diff --git a/utils/transformers/tokens.go b/utils/transformers/tokens.go index f2f2e0b..b8452b1 100644 --- a/utils/transformers/tokens.go +++ b/utils/transformers/tokens.go @@ -2,8 +2,11 @@ package transformers import ( "crypto" + "crypto/md5" "crypto/rand" "encoding/hex" + + "github.com/google/uuid" ) func GenerateRandomToken() (string, error) { @@ -14,8 +17,18 @@ func GenerateRandomToken() (string, error) { return hex.EncodeToString(bytes), nil } +func GenerateUUID() string { + return uuid.New().String() +} + func GenerateTokenFromString(input string) string { hasher := crypto.SHA256.New() hasher.Write([]byte(input)) return hex.EncodeToString(hasher.Sum(nil)) } + +func GenerateMD5Hash(data []byte) string { + hasher := md5.New() + hasher.Write(data) + return hex.EncodeToString(hasher.Sum(nil)) +} |
