웹서비스 제공에 있어서 이미지 관리는 중요한 부분중에 하나입니다. 별도의 저장 및 관리 영역이 필요한데 일반 기업형으로는 별도 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)
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 |