본문 바로가기
CLASS/JAVA

#15-1 / 이미지(binary)

by hingu 2024. 5. 22.

* 이미지(binary) - stream으로만 가능 

* stream 사용시 유의사항
 1. byte[] 변환 필요
 2. InputStream 사용시 read 필수 
 3. write를 이용할 경우 flush 사용하면 에러가 적다 : 한번 초기화해줌

⚡ 이미지 복사

-반복문 없이 처리
public static void main(String[] args) {
    try {
        String img = "D:\\webpage\\agree\\src\\main\\java\\io\\img.jpg"; //원본이미지
        FileInputStream fs = new FileInputStream(img); //파일을 로드
        byte[] by = new byte[fs.available()]; //이미지 전체 용량 byte로

        fs.read(by); //해당 이미지를 읽은 후 캐시메모리에 저장

        String cpimg = "D:\\webpage\\agree\\src\\main\\java\\io\\"; 
        FileOutputStream os = new FileOutputStream(cpimg+"img2.jpg");
        os.write(by); //복사 실행

        os.flush(); 
        os.close();
        fs.close();
    }catch(Exception e) {
        e.getMessage();
    }

}


- 반복문으로 구현

try {
    String img = "D:\\webpage\\agree\\src\\main\\java\\io\\img.jpg"; //원본이미지
    FileInputStream fs = new FileInputStream(img); //파일을 로드

    //이미지는 용량이 큰 경우가 있을수 있어 잘라서 로드하는게 좋다
    byte[] by = new byte[fs.available()/100];

    String cpimg = "D:\\webpage\\agree\\src\\main\\java\\io\\"; 
    FileOutputStream os = new FileOutputStream(cpimg+"img2.jpg");

    int b = 0; //읽은 바이트 수
    int check = 0; //읽은 횟수
    while(true) { //무한반복
        b = fs.read(by); //byte 숫자 : (전체용량/100)으로 분해 한 후 용량을 읽어들임
        if(b == -1) { //더이상 읽을 내용이 없을 경우 break;
            break;
        }else {
            //해당 범위만큼 읽고 붙이고 읽고 붙이고 반복(이미지 조합)
			  //.write(byte객체이름,0,읽은 byte숫자)
            os.write(by, 0, b); 
        }
        check++;
        if(check%2 == 0) {
            System.out.println(check + "%"); //progress bar를 만든다면.. (현재상황) 
            if(check == 50) { //이미지 절반 끊겨서 생성됨
                break;
            }
        }
    }
    os.flush();
    os.close();

    fs.close();
}catch(Exception e) {
    e.getMessage();
}

 

 

⚡ 응용
/*
 [응용문제]
 d:\ 에 product 디렉토리 상품 4개의 이미지가 있습니다.
 해당 이미지를 upload라는 디렉토리에 복사 되도록 코드를 작성하시오.
 */

public static void main(String[] args) throws Exception{
    //new file16_tbox().property();
    //new file16_tbox().directory();

    String url = "D:\\product\\";
    String cpurl = "D:\\upload\\";
    String data[] = {"pd1.jpg","pd2.jpg","pd3.jpg","pd4.jpg","pd5.jpeg"};

    int w=0;
    while(w<data.length) { //배열 갯수만큼 반복
        System.out.println(data[w]);
        String url_full = url+data[w];
        FileInputStream fs = new FileInputStream(url_full); //읽음
        byte bt[] = new byte[fs.available()]; //원시배열 규격사이즈
        fs.read(bt); //파일 전체를 읽어들임

        FileOutputStream os = new FileOutputStream(cpurl + data[w]); //저장경로
        os.write(bt);
        os.flush();

        os.close();
        fs.close();

        w++;
    }
    System.out.println("파일이 정상적으로 업로드 되었습니다");

}


참고 : https://dev-eunse.tistory.com/89  ,  https://dev-eunse.tistory.com/88

 

⚡ 파일 용량체크 업로드 방식 ( Stream + Buffered )

BufferedInputStream : byte 내용을 temp 임시 메모리에 저장
( buffer는 read라고 한번이라도 작성하는 순간 메모리 로스 - 반복문 사용 주의) 
String url = "D:\\product\\img1.png"; //2MB 이상
String url2 = "D:\\product\\img2.jpg"; //2MB 이하

try {
    InputStream is = new FileInputStream(url2);
    BufferedInputStream bs = new BufferedInputStream(is);
    //System.out.println(bs.available()); 용량체크

    if(bs.available() > 2097152) {
        System.out.println("이미지는 최대 2MB 이하만 가능");
    }else {
        byte file[] = new byte[bs.available()]; //buffer로 해당 값을 byte로 변환
        //OutputStream 사용시 파일명 변경 가능
        FileOutputStream fs = new FileOutputStream("d:\\upload\\20240522.jpeg");

        bs.read(file); //픽셀값 전체 사이즈
        fs.write(file); //byte 모두 저장
        fs.flush();
        fs.close();
        System.out.println("정상적으로 출력되었습니다");
    }

    bs.close();
    is.close();

}catch(Exception e) {
    e.getMessage();
}

 

'CLASS > JAVA' 카테고리의 다른 글

#15-3 / csv 데이터 저장  (0) 2024.05.22
#15-2 / StreamWriter,StreamReader  (0) 2024.05.22
#14-3 / Stream 활용법  (0) 2024.05.21
#14-2 / nio  (0) 2024.05.21
#14-1 / FileReader => Buffer  (0) 2024.05.21