이미지 리사이즈 처리를 위한 함수 만들기 > 개발강좌

매출이 오르면 내리는 수수료! 지금 수수료센터에서 전자결제(PG)수수료 비교견적 신청해 보세요!

개발강좌

프로그램 강좌 :
1. 유창화님의 썸네일, 정규표현식, 이미지관련 강좌
2. Sphinx 검색엔진을 이용한 도로명 주소 검색 시스템 구축

이미지 리사이즈 처리를 위한 함수 만들기 정보

썸네일 이미지 리사이즈 처리를 위한 함수 만들기

본문

대단할것은 없는 강좌이지만,
제 강좌를 출처를 밝히고 외부로 퍼가는 것은 허용하지만,
다른 강좌의 자료나 책의 자료로 사용되거나 부분적인 인용은 허용하지 않습니다.

강좌는 php 5. 대를 기준으로 하며, 기본적으로 GD 나 FREETYPE 등의 기본적인 라이브러리는 연동되었다는 가정하에 진행합니다.
예전 개발 환경에서는 GD 나 FREETYPE 등의 연동여부나 php버젼들을 따졌지만, 요새 개발 환경에서는 대부분 기본적으로 다 제공하기 때문에 그렇습니다.

이미지 리사이즈 처리를 위한 함수 만들기

이전에는 이미지 리사이즈 처리를 해보았습니다.
이번에는 자주 쓰이는 리사이즈 처리를 함수로 만들어보겠습니다.

함수를 만들기 전에 미리 알아야 할 내장함수에 대해 간단히 정리하겠습니다.

is_int
용도 : 인자로 받은 것의 데이타 타입이 정확히 정수인지 아닌지 판별, 정수일 경우 true, 정수가 아닐경우 false 를 반환합니다.

참고 :
is_int(3) ==> 양의 정수 이므로 true 를 반환
is_int('3') ==> 3이라는 문자열이므로 false 를 반환
is_int(-3) ==> 음의 정수 이므로 true 를 반환
is_int('-3') ==> -3이라는 문자열이므로 false 를 반환
is_int(3.33) ==> float 즉 소숫점 형태의 실수 이므로 false 를 반환
is_int('3.33') ==> 3.33 이라는 문자열 이므로 false 를 반환

위의 참고에서도 알수 있듯이 정확히 정수 타입일 경우에만 true를 반환 합니다.

settype
용도 :
첫번째 인자로 받은 것의 데이타 타입을 두번째 인자로 받은 데이타 타입으로 강제로 변환합니다.
사용되는 변수의 데이타 타입이 프로그램에서 필요한 데이타 타입이 아닐경우 데이타타입을 맞춰주기 위해서 사용합니다.

두번째 사용되는 인자의 종류에는
"boolean" (혹은, PHP 4.2.0부터, "bool") ==> true 나 false 로 변환
"integer" (혹은, PHP 4.2.0부터, "int") ==> 정수로 변환
"float" (PHP 4.2.0부터만 가능, 이전의 버전은 배제된 표현 "double"을 사용) ==> 소숫점인 실수로 변환
"string" ==> 문자열로 변환
"array" ==> 배열로 변환
"object" ==> 객체로 변환
"null" (PHP 4.2.0부터) ==> null 로 변환


참고 :
$val = '3';//3인 문자열
if (!is_int($val)) {//$val의 데이타 타입이 정수형이 아니라면

  settype($val, 'int');//강제로 정수형으로 데이타 타입을 변환
}


empty
용도 : 인자로 받는 변수가 비어있는지 검사합니다. 비어있다면 true, 그렇지 않다면 false를 반환합니다.

참고 :
여기서 비어있다는 말은 인자의 변수의 값이 null, false, 숫자 0, 문자열 '0', 문자열 "0", 또는 빈배열 array(), 또는 변수는 정의되어있지만 값을 지정하지 않은 경우 모두를 말합니다.

empty(0) ==> 숫자 0 이므로 true를 반환
empty('0') ==> 문자열 0 이므로 true를 반환
empty(null) ==> null 이므로 true를 반환
empty(false) ==> false 이므로 true를 반환
empty('') ==> 값이 없으므로 true를 반환
empty(array()) ==> 빈 배열 이므로 true를 반환


예제1 : lib/image_proc.function.php 에 추가

//원본의 너비, 원본의 높이, 리사이즈 너비나 높이, 기준값을 받아 기준값을 토대로 정비율의 값을 구함
//성공시 정비율의 값을 반환, 실패시 false를 반환
//기준값은 width 나 height, 기준값은 생략 가능하며 생략시 자동으로 width가 된다.
function get_size_by_rule($src_w, $src_h, $dst_size, $rule='width'){

  if (!is_int($src_w) || $src_w < 1 || !is_int($src_h) || $src_h < 1){//원본의 너비와 높이가 둘중에 하나라도 0보다 큰 정수가 아닐경우

    $GLOBALS['errormsg'] = "원본의 너비와 높이가 0보다 큰 정수가 아닙니다. ($src_w, $src_h)";

    return false;
  }

  if (!is_int($dst_size) || $dst_size < 1){//리사이즈 될 사이즈가 0보다 큰 정수가 아닐경우

    $GLOBALS['errormsg'] = "리사이즈될 사이즈가 0보다 큰 정수가 아닙니다. ($dst_size)";

    return false;
  }

  if ($rule != 'height') {//기준값이 높이가 아닌경우, 즉, 너비일 경우

    return ($dst_size / $src_w * $src_h);
  }
  else {//기준값이 높이일 경우

    return ($dst_size / $src_h * $src_w);
  }
}

lib/image_proc.function.php 파일에 위 함수 get_size_by_rule 를 추가 합니다.
get_size_by_rule 함수는 이전 내용에 다뤗던 이미지의 크기를 정비율로 구하는 부분을 함수로 만든것입니다.
이부분은 여러군데서 활용 될수 있으므로 재사용을 위해 함수로 정의 하였습니다.

get_size_by_rule($src_w, $src_h, $dst_size, $rule='width')
용도 : 원본 크기에 대해 새로운 이미지의 정비율 크기를 구할때 사용, 성공시 0보다 큰 정수를 반환, 실패시 false를 반환합니다.

인자 :
$src_w ==> 원본의 너비, 0보다 큰 정수를 사용합니다.
$src_h ==> 원본의 높이, 0보다 큰 정수를 사용합니다.
$dst_size ==> 새로 만들 이미지의 너비나 높이, 0보다 큰 정수를 사용합니다.
$rule ==> 너비를 기준으로 값을 생성할지, 높이를 기준으로 값을 생성할지 결정하는 구분자. 너비를 기준으로 할때는 width, 높이를 기준으로 할때는 height, $rule이 생략되거나, $rule 이 height 가 아닌경우에는 모두 width 로 인식합니다.

처리순서 :
1. 넘어온 원본의 너비와 높이가 0보다 큰 정수인지 체크
2. 넘어온 $dst_size 가 0보다 큰 정수 인지 체크
3. 기준값데로 값을 구하여 반환

참고 :
함수를 만들때 받을 인자를 function test_function ($v1, $v2, $v3.....) 등로 정의 하는데, 인자에 기본값을 줌으로 해서 인자를 생략 가능하게 만들수도 있습니다. 즉, 위 function get_size_by_rule($src_w, $src_h, $dst_size, $rule='width') 와 같이 함수를 정의 하면 맨 마지막 인자인 $rule 은 width 라는 기본값이 주어져 있으므로 사용시 생략가능하고, 생략했을시에는 자동으로 $rule 에는 width 의 값이 할당됩니다.


예제2 : lib/image_proc.function.php 에 추가

//원본의 리소스, 원본의 너비, 원본의 높이, 리사이즈 너비, 높이를 받아 이미지 리사이즈 처리
//성공시 리사이즈된 이미지의 리소스를 반환, 실패시 false를 반환
//$dst_h 는 생략가능, 생략시 너비 기준 정비율로 리사이즈 됨
//너비를 기준으로 정비율 생성시는 get_image_resize($src, $src_w, $src_h, $dst_w) 으로 사용
//높이를 기준으로 정비율 생성시는 get_image_resize($src, $src_w, $src_h, 0, $dst_h) 으로 사용
//지정된 크기로 강제 생성시에는 get_image_resize($src, $src_w, $src_h, $dst_w, $dst_h) 으로 사용
function get_image_resize($src, $src_w, $src_h, $dst_w, $dst_h=0){

  if (empty($src))  {//원본의 리소스가 빈값일 경우

    $GLOBALS['errormsg'] = '원본 리소스가 없습니다.';

    return false;
  }

  //정수형이 아니라면 정수형으로 강제 형변환
  if (!is_int($src_w)) settype($src_w, 'int');
  if (!is_int($src_h)) settype($src_h, 'int');
  if (!is_int($dst_w)) settype($dst_w, 'int');
  if (!is_int($dst_h)) settype($dst_h, 'int');

  if ($src_w < 1 || $src_h < 1){//원본의 너비와 높이가 둘중에 하나라도 0보다 큰 정수가 아닐경우

    $GLOBALS['errormsg'] = "원본의 너비와 높이가 0보다 큰 정수가 아닙니다. ($src_w, $src_h)";

    return false;
  }

  if (empty($dst_w) && empty($dst_h)) {//리사이즈될 너비와 높이 둘다 없을 경우

    $GLOBALS['errormsg'] = '리사이즈될 너비와 높이는 둘중에 하나는 반듯이 있어야 합니다.';

    return false;
  }

  if (!empty($dst_w) && $dst_w < 1){//리사이즈 될 너비가 존재하는데 0보다 큰 정수가 아닐경우

    $GLOBALS['errormsg'] = "리사이즈될 너비가 0보다 큰 정수가 아닙니다. ($dst_w)";

    return false;
  }

  if (!empty($dst_h) && $dst_h < 1){//리사이즈 될 높이가 존재하는데 0보다 큰 정수가 아닐경우

    $GLOBALS['errormsg'] = "리사이즈될 높이가 0보다 큰 정수가 아닙니다. ($dst_h)";

    return false;
  }


  //리사이즈 될 너비와 높이가 둘중에 하나가 없는 경우에는 정비율을 의미하며, 비율데로 너비와 높이를 결정한다.
  if (empty($dst_w) || empty($dst_h)) {

    if (empty($dst_h)) $dst_h = get_size_by_rule($src_w, $src_h, $dst_w, 'width');
    else $dst_w = get_size_by_rule($src_w, $src_h, $dst_h, 'height');
  }
 
  $dst = @imagecreatetruecolor ($dst_w , $dst_h);//만드어질 $dst_w , $dst_h 크기의 이미지 리소스를 생성한다.
  if ($dst === false) {
   
    $GLOBALS['errormsg'] = "$dst_w , $dst_h 크기의 썸네일 이미지의 리소스를 생성하지 못했습니다.";

    return false;
  }

  $result_resize = imagecopyresampled ($dst , $src , 0 , 0 , 0 , 0 , $dst_w , $dst_h , $src_w , $src_h );
  if ($result_resize === false) {
   
    $GLOBALS['errormsg'] = "$dst_w , $dst_h 크기로 리사이즈에 실패하였습니다.";

    return false;
  }

  return $dst;
}

lib/image_proc.function.php 파일에 위 함수 get_image_resize 를 추가 합니다.
get_image_resize 함수는 이전 내용에 다뤗던 이미지를 리사이즈 처리하는 부분을 함수로 구현한것입니다.

get_image_resize($src, $src_w, $src_h, $dst_w, $dst_h=0)
용도 : 원본 이미지의 리소스를 받아 새로운 크기의 썸네일 이미지를 생성하여 그 이미지의 리소스를 반환합니다. 성공시에는 이미지 리소스를 반환하고, 실패시에는 false를 반환합니다.

인자 :
$src ==> 원본의 이미지 리소스
$src_w ==> 원본의 너비, 0보다 큰 정수를 사용합니다.
$src_h ==> 원본의 높이, 0보다 큰 정수를 사용합니다.
$dst_w ==> 새로 만들 이미지의 너비를 지정합니다. 0이상의 정수를 사용합니다. 0을 사용할때는 $dst_h 에는 반듯이 0보다 크 정수를 사용해야 합니다.
$dst_h ==> 새로 만들 이미지의 높이를 지정합니다. 0이상의 정수를 사용합니다. 0을 사용할때는 $dst_w 에는 반듯이 0보다 크 정수를 사용해야 합니다. $dst_h 는 $dst_w가 0이 아닐경우 생략가능하며, 생략시에는 기본값 0으로 자동 입력됩니다.

처리순서 :
1. 원본 리소스의 값이 있는지 체크
2. 정수형으로 사용되어져야할 변수들이 정수가 아니면 정수로 강제 변환
3. 원본의 너비와 높이가 0보다 큰 정수인지 체크
4. 리사이즈 이미지의 너비 높이 둘다 값이 없는지 체크
5. 리사이즈 이미지의 너비나 높이에 값이 있을때 0보다 큰 정수인지 체크
6. 리사이즈 이미지의 너비나 높이, 둘중 하나가 없을때 정비율로 나머지 값을 구하는 부분
7. 리사이즈 이미지 리소스 생성
8. 이미지 리사이즈 처리
9. 생성된 이미지 리소스 반환

참고 :
만들어진 get_image_resize 함수를 보며, 어떤분은 "왜 원본에서 이미지 리소스를 생성하는 부분과 마지막 저장하는 부분을 같이 함수로 만들지 않지?" 라는 의문을 가질수도 있다고 봅니다.그 이유는 중복 처리를 하기 위해서 그렇습니다.

이미지 처리를 하면서 꼭 리사이즈만 처리하는 경우만 있는것이 아니라, 리사이즈 후 워터마크를 입힐경우, 글자을 넣을 경우,
필터를 적용할경우, 또 순서가 다 다를경우 등의 여러가지 경우가 발생하는데.

만약 리사이즈 함수에서 이미지 저장까지의 처리를 다 해버리면 다시 그 이미지를 읽어들이는 과정을 몇번을 더 반복해야 합니다. 따라서 그런 비효율적인 재처리를 막기 위해 처리부분만을 함수로 만든 것입니다.


이전 내용에서 했던 이미지 리사이즈 예제 test5.php를 새로 만들어진 함수와 함께 아래와 같이 수정해 보았습니다.

예제3 : test6.php

<?php

//이미지 처리 함수 인클루드
include_once 'lib/image_proc.function.php';

$path_file = 'sample_image/test.jpg';//원본파일

$path_resizefile1 = 'sample_image/test_resize_1.jpg';//리사이즈되어 저장될 파일 경로
$path_resizefile2 = 'sample_image/test_resize_2.jpg';//리사이즈되어 저장될 파일 경로
$path_resizefile3 = 'sample_image/test_resize_3.jpg';//리사이즈되어 저장될 파일 경로

$dst_w = 200;//만들어질 이미지의 너비 지정, 픽셀단위의 0이상의 정수를 지정
$dst_h = 300;//만들어질 이미지의 높이 지정, 픽셀단위의 0이상의 정수를 지정

//이미지 리소스를 받아온다.
list($src, $src_w, $src_h) = get_image_resource_from_file ($path_file);
if (empty($src)) die($GLOBALS['errormsg'] . "<br />\n");

//너비를 기준으로 정비율 생성
$dst1 = get_image_resize($src, $src_w, $src_h, $dst_w);
if ($dst1 === false) die($GLOBALS['errormsg'] . "<br />\n");

$result_save1 = save_image_from_resource ($dst1, $path_resizefile1);//저장
if ($result_save1 === false) die($GLOBALS['errormsg'] . "<br />\n");

//높이를 기준으로 정비율 생성
$dst2 = get_image_resize($src, $src_w, $src_h, 0, $dst_h);
if ($dst2 === false) die($GLOBALS['errormsg'] . "<br />\n");

$result_save2 = save_image_from_resource ($dst2, $path_resizefile2);//저장
if ($result_save2 === false) die($GLOBALS['errormsg'] . "<br />\n");

//강제 생성
$dst3 = get_image_resize($src, $src_w, $src_h, $dst_w, $dst_h);
if ($dst3 === false) die($GLOBALS['errormsg'] . "<br />\n");

$result_save3 = save_image_from_resource ($dst3, $path_resizefile3);//저장
if ($result_save3 === false) die($GLOBALS['errormsg'] . "<br />\n");

@imagedestroy($src);
@imagedestroy($dst1);
@imagedestroy($dst2);
@imagedestroy($dst3);

//성공하였다면 이미지 출력

?>
원본 이미지 <br />
<img src='<?=$path_file?>'> <br />

썸네일 이미지 - 너비기준 정비율 <?=$dst_w?>px <br />
<img src='<?=$path_resizefile1?>'> <br />

썸네일 이미지 - 높이기준 정비율 <?=$dst_h?>px <br />
<img src='<?=$path_resizefile2?>'> <br />

썸네일 이미지 - 강제지정 <?=$dst_w?>px X <?=$dst_h?>px <br />
<img src='<?=$path_resizefile3?>'> <br />
추천
4

댓글 5개

질문 좀 드려도 될까요? 이미지 리사이징 할때 원본 이미지 크기를 가져오는거 말고 브라우져 크기 인식해서 브라우져보다 큰 이미지는  브라우져 사이즈 만큼 리사이징 되서 보이게 하고 싶은데 어떻게 하면 될까요  본문에서 클릭했을때 팝업이미지를 수정하고 싶습니다.
전체 17
개발강좌 내용 검색 썸네일에서

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT