package services import ( "bytes" "context" "fmt" "image" "image/jpeg" _ "image/png" // Support PNG decoding "io" "log" "mime/multipart" "service-warungpos-go/config" "github.com/cloudinary/cloudinary-go/v2" "github.com/cloudinary/cloudinary-go/v2/api/uploader" ) // UploadToCloudinary mengompresi gambar dan mengunggahnya ke Cloudinary func UploadToCloudinary(fileHeader *multipart.FileHeader) (string, error) { // Buka file dari fileHeader file, err := fileHeader.Open() if err != nil { return "", fmt.Errorf("gagal membuka file: %v", err) } defer file.Close() // Baca seluruh bytes file contents, err := io.ReadAll(file) if err != nil { return "", fmt.Errorf("gagal membaca file: %v", err) } // Kompresi gambar ke JPEG dengan quality 75 compressedBytes, err := compressImage(contents) if err != nil { log.Printf("[CLOUDINARY] Gagal kompresi, menggunakan file asli: %v", err) compressedBytes = contents } // Inisialisasi Cloudinary dari parameter config cld, err := cloudinary.NewFromParams( config.GlobalConfig.CloudinaryCloudName, config.GlobalConfig.CloudinaryAPIKey, config.GlobalConfig.CloudinaryAPISecret, ) if err != nil { return "", fmt.Errorf("gagal inisialisasi Cloudinary: %v", err) } ctx := context.Background() // Gunakan Reader dari compressedBytes untuk upload resp, err := cld.Upload.Upload(ctx, bytes.NewReader(compressedBytes), uploader.UploadParams{ Folder: "warungpos/products", }) if err != nil { return "", fmt.Errorf("gagal upload ke Cloudinary: %v", err) } // Cloudinary SDK does not return an error when credentials or cloud name are invalid, // instead it populates the Error field in the response. We must check it! if resp.Error.Message != "" { return "", fmt.Errorf("cloudinary error: %s", resp.Error.Message) } log.Printf("[CLOUDINARY] Upload sukses! URL: %s", resp.SecureURL) return resp.SecureURL, nil } // compressImage mengompresi gambar ke JPEG (kualitas 75) func compressImage(imgBytes []byte) ([]byte, error) { // Decode gambar (mendukung JPEG/PNG/WebP jika didaftarkan) img, _, err := image.Decode(bytes.NewReader(imgBytes)) if err != nil { return nil, err } // Encode ulang sebagai JPEG dengan kualitas 75 var buf bytes.Buffer err = jpeg.Encode(&buf, img, &jpeg.Options{Quality: 75}) if err != nil { return nil, err } return buf.Bytes(), nil }