파일 업로드
const importFile = async (e) => {
// input[type='file'] 로 들어오는 내용
const files = Array.from(e.target.files);
// 위 내용을 FileReader의 readAsDataURL 로 읽어와준다.
const reader = new FileReader();
reader.readAsDataURL(files[0]);
// reader.result 는 readAsDataURL 로 읽어왔으므로 base64 타입을 띄게 된다.
reader.onload = async () => {
const url = "-";
// base64 를 ArrayBuffer -> Uint8Array 로 읽어와줘야 dicomParser 사용이 가능
const dataSet = dicomParser.parseDicom(b64toUint(reader.result));
let patientId = dataSet.string("x00100020");
let studyDate = dataSet.string("x00080020");
let seriesTime = dataSet.string("x00080031");
let instanceNumber = dataSet.string("x00200013");
await axios
.post(
url,
{
patientId: patientId,
studyDate: studyDate,
seriesTime: Math.floor(parseFloat(seriesTime)),
instanceNumber: instanceNumber,
dcmBase64: reader.result,
},
// dicom 파일을 base64 타입으로 다룰 것이므로 application/octet-stream 으로 컨텐츠 타입을 지정해준다.
{ "Content-Type": "application/octet-stream", withCredentials: true }
)
.then((response) => {
console.log("서버 성공 시 응답 데이터 : ", response.data);
});
};
};
이 짧은 내용을 며칠을 삽질했는지 모르겠다 ...
이미지나 영상이 아닌 다이콤 파일이라 base64와 Blob, File, Uint8Array 등 다양한 방식으로 데이터를 다뤄볼 수 있었다 ^^...;
하다가 잘 안풀려서 아예 파일 구조를 뜯어보자! 싶어서 추출한 base64
base64
base64는 간략하게 쓰자면 아스키 코드 64개(64진법)으로 정리한 파일이다.
data:application/octet-stream;base64, 이후에 정보가 들어간다.
ArrayBuffer
Uint8Array 로 변환하기 전 거쳐야 하는 버퍼로 읽을 수 없는 문자들로 구성되어 있다.
그래서 Uint8Array 로 변경해줘야 다룰 수 있나보다.
Uint8Array
이름처럼 보다시피 양수 정수로 이루어져 있는 배열이다. 아스키 코드를 양수로 바꿔놓은거라고 보면 된다.
// base64 를 Uint8Array 로 바꿔주는 함수
function b64toUint(b64Data) {
// base64 파일 형식의 경우 데이터 앞에 Content Type 과 파일 형식이 , 로 구분되어 있으므로
// data:application/octet-stream;base64, ~~~
// 데이터를 추출하기 위해선 ,를 기준으로 나눠줘야 한다.
// 혹시라도 분리된 파일 형식이 들어올 경우 아래의 분기문으로 걸러줌
let imageData;
const b64Split = b64Data.split(",");
if (b64Split[1] !== undefined) {
imageData = atob(b64Split[1]);
}
// base64 를 이진 데이터 배열인 ArrayBuffer,
// 그 데이터를 다루기 위한 TypedArray인 Uint8Array로 바꾸는 과정
const arraybuffer = new ArrayBuffer(imageData.length);
const view = new Uint8Array(arraybuffer);
for (let i = 0; i < imageData.length; i++) {
// 문자를 아스키코드로 변경해주는 charCodeAt() 메서드와 비트 연산자 &, 0xff(16진수) 사용하여
// 음수를 양수로 바꿔주어 양수값을 배열에 저장해준다.
view[i] = imageData.charCodeAt(i) & 0xff;
}
return view;
}
파일 저장
const saveFile = async (e) => {
const url = `-`;
const res = await axios.get(url);
const uInt8 = b64toUint(res.data[0]);
// new Blob([Uint8Array]) 로 블롭 생성
const blob = new Blob([uInt8]);
const blobUrl = window.URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = blobUrl;
a.download = "download.dcm";
document.body.appendChild(a);
a.click(); // 강제로 실행
a.remove();
window.URL.revokeObjectURL(blobUrl); // 해제 해줘야 함
};
블록 객체는 배열 형태로 Uint8Array 를 넣어줘서 만들어줄 수 있다.
블롭으로 만들면 window.URL.createObjectURL 로 해당 파일을 인터넷 상에서 접근이 가능한 URL 로 만들어줄 수 있게 된다. 그래서 임의의 a태그를 만들고 그 href 속성 안에 그 url을 넣어주면 다운로드 할 수 있는 형태가 된다.
'Web Study > React 관련' 카테고리의 다른 글
리액트 최적화 - react-icons 라이브러리 (0) | 2023.09.13 |
---|---|
Suspense를 사용하기에 앞서 (0) | 2023.09.05 |
웹 페이지 최적화의 종류 (0) | 2023.07.25 |
Custom Hooks (0) | 2023.07.21 |
React 컴포넌트 설계에 대해.. (0) | 2023.07.18 |