Java Base64와 일반 이미지 저장의 차이

최용혁·2025년 2월 4일

Base64란

Binary Data를 텍스트로 변경하는 인코딩 방식 중 하나로 바이너리 데이터를 문자 코드에 영향을 받지 않는 공통 64개의 ASCII영역의 문자들로 이루어진 문자열로 변경

Base64를 사용하는 이유

  • Base64는 HTML 또는 Email과 같이 문자를 위한 Media에 Binary Data를 포함해야 될 필요가 있을 때 포함된 Binary data가 시스템 독립적으로 동일하게 전송 또는 저장되는 것을 보장하기 위해 사용
  • Base64를 인코딩할 경우 6Bit당 2Bit의 overhead가 발생하기 때문에 전송해야 될 데이터의 양이 약 33% 늘어나고, 인코딩, 디코딩에 추가 Cpu연산까지 필요
  • 그럼에도 사용하는 이유는, 문자를전송하기 위해 설계된 Media를 이용하여 Binary Data(이미지, 오디오) 등을 전송하면 ASCII로 인코딩하여 전송하게 되면 여러가지 문제 발생할 수 있음
    -- ASCII는 7bits encoding 인데 나머지 1bit를 처리하는 방식이 시스템 별로 상이
    -- 일부 제어문자(ex:Line ending)의 경우 시스템 별로 다른 코드 값을 갖음
  • 그래서 ASCII중 제어문자와 일부 특수문자를 제외한64개의 안전한 출력 문자만 사용하는 Base64를 사용

Base64 Encode, Decode

  • 인코딩 하는 방법
    -- String ↔ byte[] 간의변환에 대해 신경써주면 된다.
    -- encoding 할때는 byte[] 를 param으로 넣어주고,
    -- decoding 할때는 decode결과를 String으로 변환해주는 정도만 주의
import static java.util.Base64.*;

public class Base64Test {
    public static void main(String[] args) {
        String test = "안녕하세요 저는 개발자입니다";
        byte[] testBytes = test.getBytes();

        Encoder encoder = getEncoder();
        Decoder decoder = getDecoder();

        byte[] encodeByte = encoder.encode(testBytes);
        byte[] decodeByte = decoder.decode(encodeByte);

        System.out.println(test);
        System.out.println(new String(encodeByte));
        System.out.println(new String(decodeByte));
    }
}
//출력
인코딩 전: 안녕하세요 저는 개발자입니다
인코딩: 7JWI64WV7ZWY7IS47JqUIOyggOuKlCDqsJzrsJzsnpDsnoXri4jri6Q=
디코딩: 안녕하세요 저는 개발자입니다

그럼 이제, 본격적으로 File을 이용한 방식과 Base64를 이용한 저장방식의 차이를 알아보겠다.

Base64toFile

  • file객체 변환하여 이름과 경로만db에 저장하고 이미지는 해당 경로에 별도 저장
  • frontend 데이터 저장 base64값을 fdata에 넣어서 서버로 전송
- frontend
fdata.append("file", base64toFile($("#imgBox").attr("src"), setNam + "_mapimage.png"));
  • backend에서는 file객체를 저장하여 이름, 경로를 나눠서 db에 저장
// backend (SVC)
// 파일 객체를 저장하여 atfPat, atfNam 변수(경로, 이름)로 저장시켜 map에 저장한후 db로 보냄
ArrayList fileList = (ArrayList) inputMap.get("__fileList__"); 
if (fileList != null && fileList.size() > 0){
	FileVO fileVO = (FileVO) fileList.get(0); 
	String atfPat =	fileVO.getFileStreCours(); 
	atfPat = atfPat.replace("/new_upload/upload", "");
	atfPat = atfPat.replace("\\", "/");
	inputMap.put("atfPat", atfPat);
	inputMap.put("atfNam", fileVO.getStreFileNm()); 
}
  • 다시 frontend에서 db에 저장된 이미지 데이터 불러오기
// 데이터 다시 불러올때 (script)
var imageUrl = "/utl/web/imageSrc.do?path=/new_upload/upload"+imgPat+"&physical="+imgNam+"&contentType=image/jpeg";
  • DB에 저장된 값

Base64를 그대로 저장(File로 변환x)

  • frontend
// frontend (script)
var base64Image = $("#imgBox").attr("src");
  • backend
// backend (SVC) String으로 변환 후 DB에 저장
String base64Image = (String)inputMap.get("imgFile");
inputMap.put("imgFile", base64Image);
  • frontend(데이터 불러오기)
// 데이터 다시 불러올때 (script) 이미지 태그의 src를 base64값으로 설정
document.getElementById("imgBox").src = response.img_file;
  • DB에 저장된 값

Base64 느낀점

  • 장점
    - Base64로 저장하면 이미지가 DB에 저장되므로 별도의 경로 관리가 필요 없음
    - 데이터 일관성 유지
  • 단점
    - 원본 이미지보다 데이터 용량이 33%증가
    • 대용량 데이터를 읽거나 쓸때 성능 문제가 발생할 수 있음
  • 기존 방식으로 하면 이미지는 지정된 경로에 저장되고 db에는 이미지명만 저장
  • 기존 방식으로 저장하면 C드라이브 아래 생긴 이미지는 절대 경로로 접근이 불가하므로 http://localhost:8080/이미지저장경로/이미지파일명.png 형식으로 접근해야함
profile
안녕하세용

0개의 댓글