본문 바로가기
프로그래밍/자바

원본과 같은 비율로 썸네일(Thumbnail) 이미지 만들기

by pentode 2018. 4. 10.

이전에 작성한 글 "Java로 썸네일(Thumbnail) 이미지 만들기" 에서는 만들 썸네일 이미지의 비율에 맞게 원본 이미지를 최대한 Crop한 다음, 그 크롭된 이미지로 썸네일을 만들어 보았습니다.

 

이 경우 썸네일 리스트가 전체적으로 보기 좋게 구성됩니다. 단점으로는 원본 이미지 비율이 썸네일 비율과 많이 차이가 날 경우, 그리고 이미지 중앙이 중요한 부분이 아닐 경우에는 이미지가 중앙을 기준으로 잘리므로 원하는 의미를 나타내기 힘들 경우가 있습니다.

 

이번에 해볼 방법은 썸네일 이미지 내에 원본 이미지를 축소해서 넣은 것처럼 원본 비율을 유지하도록 만드는 것입니다. 이 방법을 사용하면 썸네일에서도 축소된 원본 전체를 볼 수 있다는 것이 장점이 되겠습니다. 단점은 원본 비율에 따라 좌/우 또는 상/하에 남는 부분이 생기게 되므로 썸네일 리스트의 전체적인 모양이 나빠질 수 있습니다.

 

이전 글에서와 같이 이번에도 Scalr 라이브러리를 사용하여 썸네일을 만듭니다. 라이브러리를 다운로드 받는 방법을 이전 글을 참조해 주세요.

 

Scalr 라이브러리에는 이미지 주위에 주어진 픽셀 만큼 채워서 늘려주는 pad() 함수가 있습니다. 이 함수가 좌/우 또는 상/하에만 픽셀을 채주지는 못하고 상,하,좌,우 모두에 동일한 픽셀 만큼 늘려줍니다.

 

가로로 긴 이미지는 너비를 기준으로, 세로가 긴 이미지는 높이를 기준으로 썸네일 비율로 높이 또는 너비를 계산해서 계산된 길이에서 원본의 길이를 뺀값을 2로 나눠주면 padding 될 길이가 되겠습니다.

 

상,하,좌,우 모두에 패딩되므로 늘어난 이미지의 중앙을 썸네일 비율로 크롭 하면 원하는 결과를 얻을 수 있습니다. 아래는 적용된 소스 입니다.

 

private void makeThumbnail(String path, String filePath, String fileName, String fileExt)
	throws IOException {

	// 원본 이미지 입니다.
	BufferedImage srcImg = ImageIO.read(new File(filePath));

	// 썸네일 크기 입니다.
	int dw = 450, dh = 270;

	// 원본이미지 크기 입니다.
	int ow = srcImg.getWidth();
	int oh = srcImg.getHeight();

	// 늘어날 길이를 계산하여 패딩합니다.
	int pd = 0;
	if(ow > oh) {
		pd = (int)(Math.abs((dh * ow / (double)dw) - oh) / 2d);
	} else {
		pd = (int)(Math.abs((dw * oh / (double)dh) - ow) / 2d);
	}
	srcImg = Scalr.pad(srcImg, pd, Color.WHITE, Scalr.OP_ANTIALIAS);

	// 이미지 크기가 변경되었으므로 다시 구합니다.
	ow = srcImg.getWidth();
	oh = srcImg.getHeight();

	// 썸네일 비율로 크롭할 크기를 구합니다.
	int nw = ow;
	int nh = (ow * dh) / dw;
	if(nh > oh) {
		nw = (oh * dw) / dh;
		nh = oh;
	}

	// 늘려진 이미지의 중앙을 썸네일 비율로 크롭 합니다.
	BufferedImage cropImg = Scalr.crop(srcImg, (ow-nw)/2, (oh-nh)/2, nw, nh);

	// 리사이즈(썸네일 생성)
	BufferedImage destImg = Scalr.resize(cropImg, dw, dh);

	// 이미지 출력
	String thumbName = path + "THUMB_" + fileName;
	File thumbFile = new File(thumbName);
	ImageIO.write(destImg, fileExt.toUpperCase(), thumbFile);
}

 

이미지를 확장하는 부분입니다.  

 

srcImg = Scalr.pad(srcImg, pd, Color.WHITE, Scalr.OP_ANTIALIAS);

 

두 번째 인자인 pd 가 늘어날 pixel 입니다. 세 번째 인자는 늘어날 부분의 색깔을 지정할 수 있습니다. 여기서는 흰색을 지정하였습니다. 네 번째 인자는 이미지 변형에 사용되는 옵션 입니다. 안티알리아스로 지정하였습니다.

 

결과 이미지 입니다.

 

 

450 x 270 사이즈의 썸네일 내에 세로로 긴 이미지가 원본 비율대로 들어가서 만들어졌습니다. 테두리의 빨강색은 썸네일의 크기와 원본이미지의 차이를 잘 보여주기 위해 가상으로 추가된 것입니다. 원래 썸네일에는 없는 부분입니다.

 

 

반응형