웹서비스 제공에 있어서 이미지 관리는 중요한 부분중에 하나입니다. 별도의 저장 및 관리 영역이 필요한데 일반 기업형으로는 별도 Storage서버를 통해 관리하지만 클라우드 기반 서비스 또는 개인 프로젝트의 경우 AWS 등 클라우드에서 제공하는 솔루션을 사용하게 됩니다.
이번에 소개하는 Cloudinary는 이러한 저장의 고민 뿐만아니라 웹, 모바일 등 다양한 매체를 위한 기능을 제공하고 있어 개인 프로젝트를 진행하는데 무료로 사용이 가능합니다.
1. Cloudinary 소개
cloudianry는 이미지, 동영상의 업로드, 저장, 관리, 변환(사이즈, 자르기 등), URL 기반 자동 변환, 최적화 등 다양한 기능을 제공하고 있습니다.
개발 편의성을 위해 여러 플랫폼의 호환용 sdk 를 지원합니다.
(React, Node.js, Angular, PHP, Python, Vue.js, Javascript, Kotlin, iOS, Android, Java, Ruby, Flutter, React Native)
Image and Video Upload, Storage, Optimization and CDN
Streamline media management and improve user experience by automatically delivering images and videos, enhanced and optimized for every user.
cloudinary.com
2. 가입 및 비용
- 회원 가입 : 이메일, 구글, 깃허브
- 사용료 ('23년9월 기준)
무료만 이용해도 월 25크레딧 이용 가능 (1크레딧 : 1000번 파일변환 가능)
- Cloudinary 가입시 다음과 같은 사용을 위한 중요 정보가 제공된다
- Cloud Name
- API Key
- API Secret
Node.js 에서 사용하기
- 설치 : $npm i cloudinary
- 사용방법
- file upload
cloudinary.v2.uploader.upload("https://upload.wikimedia.org/wikipedia/commons/a/ae/Olympic_flag.jpg",
{ public_id: "olympic_flag" },
function(error, result) {console.log(result); });
- transform & customizing
// Transform
const url = cloudinary.url("olympic_flag", {
width: 100,
height: 150,
crop: 'fill'
});
- Optimize & deliver
(URL Endpoint / Optimization / Public Id)
https://res.cloudinary.com/freshpm/image/upload/c_scale,w_500/f_auto/q_auto/samples/bike.jpg
Dashboard 에서 사용현황 확인
3. 실 사용 예제
프로젝트에서 cloudianry 폴더를 만들고 다음과 같이 index.js 파일을 만듭니다.
const cloudinary = require("cloudinary").v2;
const { CloudinaryStorage } = require("multer-storage-cloudinary");
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET,
});
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: "PeterCamp",
allowedFormats: ["jpeg", "png", "jpg"],
},
});
module.exports = {
cloudinary,
storage,
};
cloud_name, api_key, api_secret 는 .env file에 별도 관리하고 불러서 사용합니다.
storage의 params로 cloudinary내 프로젝트 폴더를 지정하고, 파일 포맷도 지정 가능합니다.
라우트 설정에서 아래와 같이 cloudinary 사용등록합니다.
const { storage } = require("../cloudinary");
const upload = multer({ storage });
router
.route("/")
.get(catchAsync(campgrounds.index))
.post(
isLoggedIn,
upload.array("image"),
validateCampground,
catchAsync(campgrounds.createCampground)
);
upload.array로 여러 개 이미지 등록 가능 하도록 합니다.
아래와 같이 html 에서 이미지 업로드 할 때 input 으로 multiple 지정(여러 개 파일) 하고 id를 "image" 로 설정합니다.
<div class="mb-3">
<div class="input-group mb-3">
<input
type="file"
class="form-control"
id="image"
name="image"
multiple
/>
<label class="input-group-text" for="image">Upload</label>
</div>
라우터에서 호출하는 createCampground 는 아래와 같이 설정합니다.
module.exports.createCampground = async (req, res) => {
if (!req.body.campground)
throw new ExpressError("Invalid Campground Data", 400);
const campground = new Campground(req.body.campground);
campground.geometry = geoData.body.features[0].geometry;
campground.images = req.files.map((f) => ({
url: f.path,
filename: f.filename,
}));
campground.author = req.user._id;
console.log(campground);
await campground.save();
req.flash("success", "Successfully made a new campground!");
res.redirect(`/campgrounds/${campground._id}`);
};
cloudinary에서 받은 url과 filename 을 DB에 저장하기 위해 사전에 아래와 같이 Schema를 변경합니다.
const ImageSchema = new Schema({
url: String,
filename: String,
});
ImageSchema.virtual("thumbnail").get(function () {
return this.url.replace("/upload", "/upload/w_200");
});
const CampgroundSchema = new Schema({
title: String,
images: [ImageSchema],
price: Number,
description: String,
location: String,
author: {
type: Schema.Types.ObjectId,
ref: "User",
},
reviews: [
{
type: Schema.Types.ObjectId,
ref: "Review",
},
],
});
여러 개 이미지 파일 등록이 가능하기 때문에 보기 편의성과 향후 사용성을 고려하여 ImageSchema로 분리하여 등록하고 CampgraoundSchema에 images 항목에 반영합니다.
'개발활용툴' 카테고리의 다른 글
Mapbox사용법(4) - geocoding (3) | 2023.12.11 |
---|---|
Mapbox 사용법(3) Marker 표출하기 (0) | 2023.11.13 |
Mapbox 사용법 (2) - 클러스터 사용예제 (0) | 2023.11.12 |
Mapbox 사용법(1) 가입 및 기본사용 (0) | 2023.11.10 |
Lorem Picsum 개발시 사용할 샘플 이미지 활용툴 (0) | 2023.07.18 |