반응형
깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)
참고
- 깃허브 리포지토리 이미지 불러오기
- 깃허브 API로 이미지 업로드하기
- 깃허브에 업로드된 이미지 삭제하기
- 캡처한 이미지를 깃허브에 업로드하기
- 캡처한 이미지 여러 개 업로드하기
- Toast UI 에디터로 이미지를 포함한 깃허브 마크다운 저장하기
이전 글을 응용해서 여러 개의 캡처된 이미지를 업로드해 보자
여러 개의 이미지를 다루기 때문에 useState는 배열로 관리한다.
const [imageDataUrls, setImageDataUrls] = useState([]);
그리고 붙여넣기 이벤트가 발생할 때마다 배열에 이미지 URL을 추가한다.
const handleImagePaste = (event) => {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
const blob = items[i].getAsFile();
const reader = new FileReader();
reader.onloadend = () => {
const base64encoded = reader.result.split(",")[1];
// 이미지 데이터 URL을 배열에 추가
setImageDataUrls((prevUrls) => [...prevUrls, base64encoded]);
};
reader.readAsDataURL(blob);
}
}
};
해당 이미지 Data URL을 이용하여 for 문으로 여러 번 깃허브 API를 호출하면 된다.
const handleUpload = async () => {
if (imageDataUrls.length === 0) {
console.error("Please paste an image first.");
return;
}
for (let index = 0; index < imageDataUrls.length; index++) {
const base64encoded = imageDataUrls[index];
전체 코드는 다음과 같다.
import React, { useState } from "react";
import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import axios from "axios";
const Capture = () => {
const [imageDataUrls, setImageDataUrls] = useState([]);
const handleImagePaste = (event) => {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
const blob = items[i].getAsFile();
const reader = new FileReader();
reader.onloadend = () => {
const base64encoded = reader.result.split(",")[1];
// 이미지 데이터 URL을 배열에 추가
setImageDataUrls((prevUrls) => [...prevUrls, base64encoded]);
};
reader.readAsDataURL(blob);
}
}
};
const handleUpload = async () => {
if (imageDataUrls.length === 0) {
console.error("Please paste an image first.");
return;
}
for (let index = 0; index < imageDataUrls.length; index++) {
const base64encoded = imageDataUrls[index];
const filePath = `images/capture_image_${index}.jpg`;
const apiURL = `https://api.github.com/repos/bloodstrawberry/auto-test/contents/${filePath}`;
const accessToken = process.env.REACT_APP_MY_TOKEN;
try {
const response = await axios.put(
apiURL,
{
message: `Add image ${index + 1}`,
content: base64encoded,
branch: "main",
},
{
headers: {
Authorization: `token ${accessToken}`,
"Content-Type": "application/json",
},
}
);
console.log(
`Image ${index + 1} uploaded successfully:`,
response.data.content.name
);
} catch (error) {
console.error(`Error uploading image ${index + 1}:`, error);
}
await new Promise((resolve) => setTimeout(resolve, 3000)); // 3초 딜레이
}
};
return (
<Box sx={{ m: 3 }}>
<Button
sx={{ m: 2 }}
component="label"
variant="contained"
startIcon={<CloudUploadIcon />}
onClick={handleUpload}
>
GitHub Upload
</Button>
<div
onPaste={handleImagePaste}
style={{
border: "1px solid #ddd",
padding: "20px",
textAlign: "center",
}}
>
<h1>이미지 붙여넣기</h1>
{imageDataUrls.map((dataUrl, index) => (
<img
key={index}
src={`data:image/png;base64,${dataUrl}`}
/>
))}
</div>
</Box>
);
};
export default Capture;
파일 덮어쓰기
현재 파일 이름을 고정했기 때문에 다시 파일을 업로드하면 아래와 같이 에러가 발생한다.
이전 글과 마찬가지로 아래와 같이 수정 가능하다.
const handleUpload = async () => {
if (imageDataUrls.length === 0) {
console.error("Please paste an image first.");
return;
}
for (let index = 0; index < imageDataUrls.length; index++) {
const base64encoded = imageDataUrls[index];
const filePath = `images/capture_image_${index}.jpg`;
const apiUrl = `https://api.github.com/repos/bloodstrawberry/auto-test/contents/${filePath}`;
const accessToken = process.env.REACT_APP_MY_TOKEN;
try {
// 이미지 업로드 전에 파일의 SHA 값 얻기
const existingFileResponse = await axios.get(apiUrl, {
headers: {
Authorization: `token ${accessToken}`,
},
});
const sha = existingFileResponse.data.sha;
// 이미지 업로드 또는 덮어쓰기
const response = await axios.put(
apiUrl,
{
message: `Add image ${index + 1}`,
content: base64encoded,
branch: "main",
sha: sha, // SHA 값 전달
},
{
headers: {
Authorization: `token ${accessToken}`,
"Content-Type": "application/json",
},
}
);
console.log(
`Image ${index + 1} uploaded successfully:`,
response.data.content.name
);
} catch (error) {
console.error(`Error uploading image ${index + 1}:`, error);
}
await new Promise((resolve) => setTimeout(resolve, 3000)); // 3초 딜레이
}
};
참고로 위의 코드는 파일이 이미 있는 경우에만 동작한다.
실제 코드에서는 파일이 존재한다면 기존 방식대로, 그렇지 않다면 위의 방식대로 하는 절차가 필요할 수 있다.
반응형
'개발 > React' 카테고리의 다른 글
리액트 - 리덕스로 로그인 상태 관리하기 (Managing Login State with Redux) (0) | 2024.01.22 |
---|---|
리액트 - Toast UI 에디터로 이미지를 포함한 깃허브 마크다운 저장하기 (Toast UI Markdown Editor) (0) | 2024.01.17 |
리액트 - 캡처한 이미지를 깃허브에 업로드하기 (Upload Captured Image to GitHub) (0) | 2024.01.17 |
리액트 - 깃허브에 업로드된 이미지 삭제하기 (Delete an Uploaded Image on GitHub) (0) | 2024.01.17 |
리액트 - 깃허브 API로 이미지 업로드하기 (Upload Images with GitHub RESTful API) (0) | 2024.01.17 |
댓글