[Java] Thumbnail Image 만드는 코드

코드 정리하다가 블로그에 정리되지 않은 코드가 있어 정리해 봅니다. 일반적인 이미지를 작은 이미지, 즉 썸네일 이미지로 만들어 주는 코드입니다. 이미지의 종횡비 크기를 유지하며 썸네일 이미지를 만들어 줍니다. 썸네일 이미지 만드는 코드를 실제 프로젝트에 붙이기 위해 만들다 보니, 부가적인 내용이 덧붙여 있으니 참고하시기 바랍니다.

사용은 아래처럼 하면 됩니다. 즉, d:/a.jpg 파일을 썸네일 이미지를 만드는데, 가로 또는 세로 크기 중 하나를 256을 만듭니다.

reateThumbnail("d:/a.jpg", 256);

아래는 d:/a.jpg의 실제 이미지입니다. 이미지 크기는 920×600입니다.

위의 이미지가 위의 코드를 통해 아래와 같이 d:/a.thumbnail.jpg 파일로 만들어지고 크기는 256×166이 됩니다. 원본 이미지의 가로 크기가 세로보다 길다보니 가로를 256으로 만들어지게 되는 것입니다.

createThumbnail 함수는 아래와 같습니다.

private static boolean createThumbnail(String fileName, int maxSize) {
    try {
        int thumbnail_width = maxSize;
        int thumbnail_height = maxSize;

        File origin_file_name = new File(fileName);
		    
        String ext = getFileExt(fileName);
        String newFileName = fileName.replace("." + ext, ".thumbnail." + ext);
		    
        BufferedImage buffer_original_image = ImageIO.read(origin_file_name);
		    
        double imgWidth = buffer_original_image.getWidth();
        double imgHeight = buffer_original_image.getHeight();
		    
        if(imgWidth < imgHeight) {
            thumbnail_width = (int)((imgWidth / imgHeight) * maxSize);
        } else {
            thumbnail_height = (int)((imgHeight / imgWidth) * maxSize);
        }
		    
        int imgType = (buffer_original_image.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage buffer_thumbnail_image = new BufferedImage(thumbnail_width, thumbnail_height, imgType);
        Graphics2D graphic = buffer_thumbnail_image.createGraphics();
		    
        graphic.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        graphic.drawImage(buffer_original_image, 0, 0, thumbnail_width, thumbnail_height, null);
		    
        if(ext.equalsIgnoreCase("jpg")) {
            writeJpeg(buffer_thumbnail_image, newFileName, 1.0f);
        } else {
            File thumb_file_name = new File(newFileName);
            ImageIO.write(buffer_thumbnail_image, ext.toLowerCase(), thumb_file_name);
        }
		    
        graphic.dispose();
    } catch (Exception e) {
        e.printStackTrace(System.err);
        return false;
    }
		
    return true;
}

위의 함수는 2개의 내부 함수를 호출하고 있는데, 해당되는 함수들은 아래와 같습니다.

private static String getFileExt(String fileName) { // "abc.txt" -> "txt", not ".txt"
    int i = fileName.lastIndexOf('.');
    int p = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));

    if (i > p) {
        return fileName.substring(i+1);
    }

    return null;
}
	 
private static void writeJpeg(BufferedImage image, String destFile, float quality) throws IOException {
    ImageWriter writer = null;
    FileImageOutputStream output = null;
		  
    try {
        writer = ImageIO.getImageWritersByFormatName("jpeg").next();
	
        ImageWriteParam param = writer.getDefaultWriteParam();
		    
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(quality);
		    
        output = new FileImageOutputStream(new File(destFile));
        writer.setOutput(output);
		    
        IIOImage iioImage = new IIOImage(image, null, null);
        writer.write(null, iioImage, param);
    } catch (IOException ex) {
        throw ex;
    } finally {
        if (writer != null) {
            writer.dispose();
        }
		    
        if (output != null) {
            output.close();
        }
    }
}

단위 테스트로 만들어 놓은 코드인지라 최적화가 되어 있지 않으니, 살펴보시고 최적화 해 사용하시기 바랍니다.

웹에서 Javascript 만으로 텍스트 파일 읽기

웹에서 JS 언어만으로 로컬에 저장된 텍스트 파일을 읽어 오는 코드를 정리한 글이다. 먼저 아래는 예제 코드 실행을 위한 DOM 구성에 대한 코드이다.


...

Open 버튼을 클릭하면 텍스트 파일을 선택할 수 있는 대화상자가 표시되도록 하며, 여기서 읽고자 하는 파일을 사용자가 선택하면 id가 output인 div에 텍스트 파일의 내용을 출력한다. 이에 대한 코드는 아래와 같다.

function openTextFile() {
    var input = document.createElement("input");

    input.type = "file";
    input.accept = "text/plain"; // 확장자가 xxx, yyy 일때, ".xxx, .yyy"

    input.onchange = function (event) {
        processFile(event.target.files[0]);
    };

    input.click();
}

function processFile(file) {
    var reader = new FileReader();

    reader.onload = function () {
        output.innerText = reader.result;
    };

    reader.readAsText(file, /* optional */ "euc-kr");
}

openTextFile은 Open 버튼 클릭시 호출하는 함수이다. processFile은 openTextFile에서 호출되는 함수로 선택된 파일을 읽어 div에 그 내용을 출력한다. IE와 Chrome 모두에서 정상적으로 작동하는 것을 확인했다.