반응형
깃허브 데스크탑으로 프로젝트 관리하기 강의 오픈!! (인프런 바로가기)
참고
- 깃허브 리포지토리 이미지 불러오기
- 깃허브 API로 이미지 업로드하기
- 깃허브에 업로드된 이미지 삭제하기
- 캡처한 이미지를 깃허브에 업로드하기
- 캡처한 이미지 여러 개 업로드하기
- Toast UI 에디터로 이미지를 포함한 깃허브 마크다운 저장하기
이번에는 이미지 파일을 업로드하지 말고, 캡처한 이미지를 깃허브에 올려보자.
링크를 참고하여 캡처한 이미지를 먼저 웹 페이지에 붙여 넣는 코드에서 보완해 나가자
import React, { useState } from "react";
const Capture = () => {
const [image, setImage] = useState(null);
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.onload = () => {
setImage(reader.result);
};
reader.readAsDataURL(blob);
break;
}
}
};
return (
<div
onPaste={handleImagePaste}
style={{ border: "1px solid #ddd", padding: "20px", textAlign: "center" }}
>
<h1>이미지 붙여넣기</h1>
{image && <img src={image} />}
</div>
);
};
export default Capture;
캡처 로직 수정
handleImagePaste는 blob을 setImage로 저장만 하고 그대로 종료한다.
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();
setImage(blob);
break;
}
}
};
그리고 이미지 태그를 아래와 같이 수정한다.
{image && <img src={URL.createObjectURL(image)} alt="Pasted" />}
업로드를 할 때 파일의 메타데이터인 blob을 같이 보내기 위해서 위의 수정이 필요하다.
handleUpload 구현
이제 깃허브 API로 이미지 업로드하기를 참고하여 handleUpload를 아래와 같이 구현하자.
const handleUpload = () => {
if (!image) {
console.error("Please select an image first.");
return;
}
const reader = new FileReader();
reader.onloadend = () => {
const base64encoded = reader.result.split(",")[1];
const filePath = "images/capture_image.jpg";
const apiURL = `https://api.github.com/repos/bloodstrawberry/auto-test/contents/${filePath}`;
const accessToken = process.env.REACT_APP_MY_TOKEN;
axios
.put(
apiURL,
{
message: "Add image",
content: base64encoded,
branch: "main", // Update with your branch name
},
{
headers: {
Authorization: `token ${accessToken}`,
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log(
"Image uploaded successfully:",
response.data.content.name
);
})
.catch((error) => {
console.error("Error uploading image:", error);
});
};
reader.readAsDataURL(image);
};
전체 코드는 다음과 같다.
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 [image, setImage] = useState(null);
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();
setImage(blob);
break;
}
}
};
const handleUpload = () => {
if (!image) {
console.error("Please select an image first.");
return;
}
const reader = new FileReader();
reader.onloadend = () => {
const base64encoded = reader.result.split(",")[1];
const filePath = "images/capture_image.jpg";
const apiURL = `https://api.github.com/repos/bloodstrawberry/auto-test/contents/${filePath}`;
const accessToken = process.env.REACT_APP_MY_TOKEN;
axios
.put(
apiURL,
{
message: "Add image",
content: base64encoded,
branch: "main", // Update with your branch name
},
{
headers: {
Authorization: `token ${accessToken}`,
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log(
"Image uploaded successfully:",
response.data.content.name
);
})
.catch((error) => {
console.error("Error uploading image:", error);
});
};
reader.readAsDataURL(image);
};
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>
{image && <img src={URL.createObjectURL(image)} alt="Pasted" />}
</div>
</Box>
);
};
export default Capture;
파일 덮어쓰기
현재 파일 이름을 고정했기 때문에 다시 파일을 업로드하면 아래와 같이 에러가 발생한다.
이 경우는 sha를 얻은 다음에 put을 하면 파일을 덮어쓸 수 있다.
handleUpload를 아래와 같이 변경하자.
const handleUpload = () => {
if (!image) {
console.error("Please select an image first.");
return;
}
const filePath = "images/capture_image.jpg";
const apiURL = `https://api.github.com/repos/bloodstrawberry/auto-test/contents/${filePath}`;
const accessToken = process.env.REACT_APP_MY_TOKEN;
const reader = new FileReader();
reader.onloadend = () => {
const base64encoded = reader.result.split(",")[1];
axios
.get(apiURL, {
headers: {
Authorization: `token ${accessToken}`,
},
})
.then((response) => {
const sha = response.data.sha;
axios
.put(
apiURL,
{
message: "Update image",
content: base64encoded,
branch: "main", // Update with your branch name
sha: sha,
committer: {
name: "bloodstrawberry",
email: "bloodstrawberry@gmail.com",
},
author: {
name: "bloodstrawberry",
email: "bloodstrawberry@gmail.com",
},
},
{
headers: {
Authorization: `token ${accessToken}`,
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log(
"Image updated successfully:",
response.data.content.name
);
})
.catch((error) => {
console.error("Error updating image:", error);
});
})
.catch((error) => {
console.error("Error fetching existing image details:", error);
});
};
reader.readAsDataURL(image);
};
참고로 위의 코드는 파일이 이미 있는 경우에만 동작한다.
실제 코드에서는 파일이 존재한다면 기존 방식대로, 그렇지 않다면 위의 방식대로 하는 절차가 필요할 수 있다.
반응형
댓글