MapleStory Finger Point

๐Ÿ”˜ ํ”„๋กœ์ ํŠธ

[ํ”„๋กœ์ ํŠธ/Reactjs] ์ด๋ฏธ์ง€ ํด๋ผ์šฐ๋“œ ์ฒ˜๋ฆฌํ•˜๊ธฐ (cloudinary)

HYEJU01 2025. 2. 6. 05:49
 

๋ชฉ์ฐจ

 

     

     

     

    0) ์ด๋ฏธ์ง€ ํด๋ผ์šฐ๋“œ ์ฒ˜๋ฆฌ

     

    ํ”„๋กœ์ ํŠธ ์ง„ํ–‰ ์ค‘ ์ด๋ฏธ์ง€๋ฅผ ํด๋ผ์šฐ๋“œ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋กœ ํ•˜๋ฉด์„œ

    ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ๋ชจ์ƒ‰ํ•˜๋˜ ๋„์ค‘ cloudinary ๋ผ๋Š” ์‚ฌ์ดํŠธ๋ฅผ ํ†ตํ•œ ํด๋ผ์šฐ๋“œํ™” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ƒˆ๋‹ค.

     

    ๊ฐ„๋‹จํ•œ ํ”„๋กœ์ ํŠธ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์˜ˆ์ •์ด๋ผ๋ฉด ์•ˆ์„ฑ๋งž์ถค์ด๋‹ค.

     

    ์ผ๋‹จ ๋น„์šฉ์ด ๋“ค์ง€ ์•Š์œผ๋ฉฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฌด๋ฃŒ ์šฉ๋Ÿ‰์ด ์ œ๊ณต๋˜์–ด์„œ ๋งค์šฐ ์ข‹๋‹ค.

    ๊ตฌํ˜„๋ฐฉ๋ฒ•๋„ ๊ฐ„๋‹จํ•˜๊ณ  ํŽธ๋ฆฌํ•˜๊ณ , ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์ด ๋งŽ๋‹ค.

     

     

    1) cloudinary ๊ฐ€์ž…ํ•˜๊ธฐ

     

    https://console.cloudinary.com/

     

    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) ํ”„๋ฆฌ์…‹ ์„ค์ • (API key)

     

    ํ™ˆ์œผ๋กœ ์˜ค๋ฉด ์ด๋Ÿฐ ํ™”๋ฉด์ด ๋œฌ๋‹ค. 

    ๋Œ€์‹œ๋ณด๋“œ์—์„œ๋Š” ๋‚ด Cloud name ๊ณผ API keys ๋ฅผ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

    (API ํ‚ค ์‚ฌ์šฉ ์—†์ด ์ž‘์—…ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์‚ฌ์šฉํ•˜์ง„ ์•Š์•˜๋‹ค.)

     

     

     

    ์ขŒ์ธก ํ•˜๋‹จ์— `์„ค์ • ๋ฒ„ํŠผ` > `Upload`

     

     

    Preset ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. 

     

    Mode : `Unsigned` ์‚ฌ์šฉ์ž ์ธ์ฆ ์—†์ด ์—…๋กœ๋“œ ํ—ˆ์šฉ ๊ฐ€๋Šฅ

    Setting :  `Upload Preset`  ๊ณต๊ฐœ์ ์œผ๋กœ ์„ค์ •๋˜์–ด ์žˆ๋‹ค๋ฉด API ํ‚ค ์—†์ด ์—…๋กœ๋“œ ๊ฐ€๋Šฅ

     

     

     

     

     

     

    3) ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ๊ตฌํ˜„ (ํ”„๋กœ์ ํŠธ)

     

     

     

     


    ์˜ˆ์•ฝ์ด ์™„๋ฃŒ๋œ ๊ฒฝ์šฐ, ์˜ˆ์•ฝ ๋‚ด์—ญ์—์„œ ๋ฆฌ๋ทฐ ์ž‘์„ฑ ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ฆฌ๋ทฐ ์ž‘์„ฑ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

    ๋ฆฌ๋ทฐ ์ž‘์„ฑ ํŽ˜์ด์ง€์—์„œ๋Š” ์ตœ๋Œ€ 4์žฅ์˜ ๋ฆฌ๋ทฐ์‚ฌ์ง„์„ ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

     

     

     

     

     

     

    ์ž‘์„ฑํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์„œ

    ์ด๋ฏธ์ง€๊ฐ€ ํด๋ผ์šฐ๋“œ์— ์—…๋กœ๋“œ ๋˜๊ธฐ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

     

     

     

     

     

    formData ์— ์—…๋กœ๋“œ ํ•  `file` ๊ณผ `upload_preset` ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

     

     

     

     

      const handleUpload = async () => {
    
        if (!images || images.length === 0) { // ์ด๋ฏธ์ง€๊ฐ€ ์—†์œผ๋ฉด ๋นˆ ๋ฐฐ์—ด ๋ฐ˜ํ™˜
          return [];
        }
    
        const uploadedUrls = []; // ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€ URL์„ ์ €์žฅํ•  ๋ฐฐ์—ด
    
        for (let i = 0; i < images.length; i++) {
          const formData = new FormData();
          formData.append('file', images[i]);
          formData.append('upload_preset', 'PRESET_NAME'); //
    
          try {
            const response = await axios.post(
              'https://api.cloudinary.com/v1_1/'CLOUD_NAME'/image/upload',
              formData
            );
            if (response.data && response.data.secure_url) {
              uploadedUrls.push(response.data.secure_url);
            }
          } catch (error) {
            console.error('์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์˜ค๋ฅ˜:', error);
          }
        }
    
        console.log('Uploaded Images:', uploadedUrls);
        return uploadedUrls; // ๋ชจ๋“  ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€ URL ๋ฐฐ์—ด ๋ฐ˜ํ™˜
      };

     

     

    ์—…๋กœ๋“œํ•  ์ด๋ฏธ์ง€๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” `return`

    ์ €์žฅํ•  ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์œผ๋ฉด ๊ฐœ๋ณ„์ ์œผ๋กœ

    cloudinary Rest API ์š”์ฒญ URL ์„ ํ†ตํ•ด์„œ ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œํ•ด์ค€๋‹ค.

    ์ดํ›„ ์—…๋กœ๋“œ ๋œ ๋งํฌ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ค€๋‹ค.

    ํด๋ผ์šฐ๋“œํ™”๋œ ์ด๋ฏธ์ง€ ๋งํฌ๋ฅผ ๋ฐฐ์—ด์— ๋‹ค์‹œ ๋‹ด์•„์„œ db ๋กœ ๋ณด๋‚ด์ฃผ๋Š” ๋ฐฉ์‹์ด๋‹ค.

     

     

     

     

     

    Media Explorer ์—์„œ ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€๋“ค์„ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

     

     

     

     

     

     

    ์ตœ์ข…์ ์œผ๋กœ db ์— ์ด๋Ÿฐ์‹์œผ๋กœ ์ €์žฅ๋˜๊ณ  

     

     

     

    ์ถœ๋ ฅํ• ๋• ๊ทธ๋Œ€๋กœ src ์— ๋„ฃ์œผ๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.