유

php > 내가 만들어 쓰는 함수 > 원본이미지를 정비율로 리사이즈 처리하기

· 2010-02-11 (목) 12:17:32 · 3937
대단할것은 없는 강좌이지만,
제 강좌를 출처를 밝히고 외부로 퍼가는 것은 허용하지만,
다른 강좌의 자료나 책의 자료로 사용되거나 부분적인 인용은 허용하지 않습니다.

 

강좌는 php 5. 대를 기준으로 하며, 기본적으로 GD 나 FREETYPE 등의
기본적인 라이브러리는 연동되었다는 가정하에 진행합니다.

예전 개발 환경에서는 GD 나 FREETYPE 등의 연동여부나 php버젼들을 따졌지만,
요새 개발 환경에서는 대부분 기본적으로 다 제공하기 때문에 그렇습니다.



php > 내가 만들어 쓰는 함수 > 원본이미지를 정비율로 리사이즈 처리하기

이전에는 이미지 처리에 필요한 기본함수 두개를 만들어 보았습니다.
이번에는 썸네일 생성등에 많이 쓰이는 이미지 정비율 리사이즈를 예제로 통해 알아보도록 하겠습니다.

이미지 리사이즈 처리를 하기 위해선 먼저 알아야 할 몇가지 내장함수가 있습니다.
그것부터 먼저 이해하고 다음 과정으로 넘어가고자 합니다.

imagecreatetruecolor ( int $width , int $height )
설명 : 지정된 너비와 높이로 true color 이미지 리소스를 생성합니다. 성공시에는 이미지리소스를 반환, 실패시에는 false 를 반환합니다.
인자 : 이미지의 크기를 지정하는 너비와 높이를 받습니다. 픽셀 단위의 0보다 큰 정수를 사용합니다.


imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
설명 :
원본을 복사하여 크기를 리사이즈 한후에 GD 라이브러리가 이미지를 재구성하여 복사본을 만듭니다. 성공시에는 true, 실패시에는 false 를 반환합니다.
인자 :
  $dst_image -> 복사본으로 만들어질 이미지의 리소스
  $src_image -> 원본 이미지의 리소스
  $dst_x -> 복사본에 복사할 시작점의 x좌표
  $dst_y -> 복사본에 복사할 시작점의 y좌표
  $src_x -> 원본에서 복사되어질 부분의 시작점의 x좌표
  $src_y -> 원본에서 복사되어질 부분의 시작점의 y좌표
  $dst_w -> 복사본 이미지의 너비
  $dst_h -> 복사본 이미지의 높이
  $src_w -> 원본 이미지의 너비
  $src_h -> 원본 이미지의 높이

imagecopyresampled
함수의 인자설명에서 나와있듯이 이미지 리사이즈를 하기 위해서는 이미지 원본의 너비와 높이 정보가 필요합니다.
그런데 우리가 이전에 만들엇던 get_image_resource_from_file 함수는 이미지의 원본으로 이미지 리소스를 받아오지만 리턴값은 이미지 리소스만 있기 때문에 이미지 리사이즈를 하기 위해선 다시 getimagesize를 중복 사용해야만 하는 비효율성이 있습니다.
그래서, get_image_resource_from_file 를 먼저 조금 수정하도록 합니다.

예제1 : get_image_resource_from_file

//특정 이미지파일(gif, jpg, png 만 지원)의 경로로 부터 이미지 리소스를 받아온다. 리턴값은 성공시에는 이미지리소스와 이미지 정보가 담긴 배열을 반환, 실패시에는 빈 배열을 반환
function get_image_resource_from_file ($path_file){ 

  if (!is_file($path_file)) {//파일이 아니라면

    $GLOBALS['errormsg'] = $path_file . '은 파일이 아닙니다.';

    return Array();
  }
   
  $size = @getimagesize($path_file);
  if (empty($size[2])) {//이미지 타입이 없다면

    $GLOBALS['errormsg'] = $path_file . '은 이미지 파일이 아닙니다.';

    return Array();
  }

  if ($size[2] != 1 && $size[2] != 2 && $size[2] != 3) {//지원하는 이미지 타입이 아니라면

    $GLOBALS['errormsg'] = $path_file . '은 gif 나 jpg, png 파일이 아닙니다.';

    return Array();
  }

  switch($size[2]){

    case 1 : //gif

      $im = @imagecreatefromgif($path_file);

      break;

  

    case 2 : //jpg

      $im = @imagecreatefromjpeg($path_file);

      break;

  

    case 3 : //png

      $im = @imagecreatefrompng($path_file);

      break;
  }

  if ($im === false) {//이미지 리소스를 가져오기에 실패하였다면

    $GLOBALS['errormsg'] = $path_file . ' 에서 이미지 리소스를 가져오는 것에 실패하였습니다.';

    return Array();
  }
  else {//이미지 리소스를 가져오기에 성공하였다면

    $return = $size;
    $return[0] = $im;
    $return[1] = $size[0];//너비
    $return[2] = $size[1];//높이
    $return[3] = $size[2];//이미지타입
    $return[4] = $size[3];//이미지 attr

    return $return;
  }
}


원래 get_image_resource_from_file 함수에서 수정된 부분을 설명하자면, 다른 모든 처리는 그대로 이고, 이미지 정보의 재사용을 위해 리턴값만 변경해 주었습니다. 

기존에는 실패시 false 를 반환하던것을 빈배열로 반환하고,
기존에는 return $im; 이었던 것을
$return = $size;
$return[0] = $im;
$return[1] = $size[0];//너비
$return[2] = $size[1];//높이
$return[3] = $size[2];//이미지타입
$return[4] = $size[3];//이미지 attr

return $return;
이렇게 변경하여 주었습니다.

이전에 사용시에는 $im = get_image_resource_from_file ('원본 이미지 경로'); 였지만, 수정후 사용시에는 list($im, $width, $height, $type) = get_image_resource_from_file ('원본 이미지 경로'); 와 같이 사용합니다.

수정된 함수를 가지고 이전의 test3.php 파일을 test4.php 파일로 수정해 보도록 하겠습니다.

예제2 : test4.php


<?php

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


$path_file1 = 'sample_image/nofile.jpg';//존재하지 않는 파일
$path_file2 = 'sample_image/test.jpg';//실제 존재하는 원본파일
$path_copyfile1 = 'sample_image/test_copy.gif';//이미 이전 테스트에서 생성한 이미지
$path_copyfile2 = 'sample_image/test_copy_2.gif';
$path_copyfile3 = 'sample_image/test_copy_2.jpg';
$path_copyfile4 = 'sample_image/test_copy_2.png';
$path_copyfile5 = 'sample_image/test_copy2';//확장자가 없는 이미지 저장경로


//이미지 리소스를 받아온다.
list($im1, $im1_width, $im1_height, $im1_type) = get_image_resource_from_file ($path_file1);
if (empty($im1)) echo $GLOBALS['errormsg'] . "<br />\n";

list($im2, $im2_width, $im2_height, $im2_type) = $a = get_image_resource_from_file ($path_file2);
if (empty($im2)) echo $GLOBALS['errormsg'] . "<br />\n";


//원본이미지의 정보를 확인한다.
echo $path_file2 . " 의 너비는 " . $im2_width . ", 높이는 " . $im2_height . " 입니다.<br />\n";


//이미지를 새로운 이름으로 저장한다.
$result_save1 = save_image_from_resource ($im2, $path_copyfile1);
if ($result_save1 === false) echo $GLOBALS['errormsg'] . "<br />\n";
else echo $path_copyfile1 . " 에 이미지가 복사되었습니다.<br />\n";

$result_save2 = save_image_from_resource ($im2, $path_copyfile2);
if ($result_save2 === false) echo $GLOBALS['errormsg'] . "<br />\n";
else echo $path_copyfile2 . " 에 이미지가 복사되었습니다.<br />\n";

$result_save3 = save_image_from_resource ($im2, $path_copyfile3);
if ($result_save3 === false) echo $GLOBALS['errormsg'] . "<br />\n";
else echo $path_copyfile3 . " 에 이미지가 복사되었습니다.<br />\n";

$result_save4 = save_image_from_resource ($im2, $path_copyfile4);
if ($result_save4 === false) echo $GLOBALS['errormsg'] . "<br />\n";
else echo $path_copyfile4 . " 에 이미지가 복사되었습니다.<br />\n";

$result_save5 = save_image_from_resource ($im2, $path_copyfile5);
if ($result_save5 === false) echo $GLOBALS['errormsg'] . "<br />\n";
else echo $path_copyfile5 . " 에 이미지가 복사되었습니다.<br />\n";


@imagedestroy($im2);

?>

이미지를 정비율로 리사이즈 하기 위해서는 약간의 수학 공식을 알아야 합니다.
중학교때를 생각하며 다음 문제를 봅니다.

문제 > X1의 값은 200 이고 Y1 의 값은 500 이라고 할때 X2가 100 의 값을 가진다면 Y2 는 얼마인가?
풀이 >
X1 : Y1 = X2 : Y2
X1 * Y2 = Y1 * X2
Y2 = (Y1 * X2) / X1 또는, 곱하기 나누기는 순서를 바꿔도 상관없으니까 Y2 = (X2 / X1) * Y1 로도 할수 있습니다.
따라서 Y2 = (100 / 200) * 500 에 의해 250 이다.


오래 되서 맞는 지는 모르겟지만 이랬던거 같습니다.
아무튼 썸네일의 높이를 구하기 위해서는 만들고자 하는 썸네일의 너비 나누기 원본의 너비 곱하기 원본의 높이입니다.
이것을 프로그램에서는

$resize_rule = $dst_w / $src_w; //비율을 구한다.
$dst_h = $resize_rule * $src_h;

입니다. 반대의 경우, 즉 썸네일의 높이를 알고 있을때 썸네일의 너비를 구할때는

$resize_rule = $dst_h / $src_h; //비율을 구한다.
$dst_w = $resize_rule * $src_w;

와 같이 합니다.


이미지 정비율로 리사이즈 처리하기 위해서 필요한 부분들은 모두 익혔고, 이미지를 정비율로 리사이즈하는 처리는 test5.php 예제와 같습니다.

예제 3: test5.php


<?php

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


$path_file = 'sample_image/test.jpg';//원본파일
$path_resizefile = 'sample_image/test_resize.jpg';//리사이즈되어 저장될 파일 경로
$dst_w = 200;//만들어질 이미지의 너비 지정, 픽셀단위의 0이상의 정수를 지정

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

//만들어질 이미지의 높이를 결정한다.
$resize_rule = $dst_w / $src_w;
$dst_h = ceil($resize_rule * $src_h);//소숫점이 나올것을 대비하여 무조건 올림을 한다.

$dst = @imagecreatetruecolor ($dst_w , $dst_h);//만드어질 $dst_w , $dst_h 크기의 이미지 리소스를 생성한다.
if ($dst === false) die("$dst_w , $dst_h 크기의 썸네일 이미지의 리소스를 생성하지 못했습니다.<br />\n");

$result_resize = imagecopyresampled ($dst , $src , 0 , 0 , 0 , 0 , $dst_w , $dst_h , $src_w , $src_h );
if ($result_resize === false) die("리사이즈에 실패하였습니다.<br />\n");

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

@imagedestroy($src);
@imagedestroy($dst);


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

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

[이 게시물은 관리자님에 의해 2011-10-31 17:16:08 PHP & HTML에서 이동 됨]
|
댓글을 작성하시려면 로그인이 필요합니다.

프로그램

8,188건
+
제목 글쓴이 날짜 조회
10-09-25 조회 2,704
10-09-19 조회 2,741
10-09-15 조회 2,743
10-09-15 조회 4,148
10-09-15 조회 3,367
10-09-15 조회 2,478
10-09-07 조회 3,591
10-08-27 조회 4,048
10-06-11 조회 4,205
10-05-31 조회 2,456
10-02-27 조회 4,988
10-02-09 조회 3,734
09-10-10 조회 7,326
09-03-19 조회 3,169
09-02-09 조회 3,448
09-02-09 조회 4,517
08-11-01 조회 2,899
08-09-29 조회 4,550
08-09-26 조회 3,507
08-09-26 조회 3,585
08-09-26 조회 2,720
08-09-26 조회 3,763
08-09-26 조회 3,484
08-09-26 조회 4,248
08-09-18 조회 3,559
08-09-09 조회 3,213
08-08-28 조회 2,754
08-07-06 조회 3,531
08-05-21 조회 4,685
08-05-13 조회 4,525
08-04-17 조회 4,898
08-02-19 조회 3,527
08-01-18 조회 3,831
08-01-10 조회 3,799
07-10-22 조회 3,640
07-10-09 조회 4,269
07-10-03 조회 3,495
07-07-06 조회 4,205
07-07-06 조회 4,418
07-07-06 조회 4,029
07-06-28 조회 3,553
07-06-05 조회 3,556
07-06-05 조회 4,099
07-05-30 조회 3,269
07-05-02 조회 3,679
07-04-15 조회 5,088
07-04-11 조회 3,618
07-04-05 조회 3,908
07-03-31 조회 3,141
07-03-31 조회 4,116
07-03-30 조회 3,720
07-03-24 조회 3,996
07-03-22 조회 3,649
07-03-12 조회 4,399
07-02-16 조회 3,256
07-02-14 조회 5,154
07-02-10 조회 3,982
07-02-09 조회 4,369
07-01-19 조회 4,030
07-01-16 조회 4,958
06-12-16 조회 5,824
06-11-30 조회 3,581
06-11-25 조회 3,682
06-10-15 조회 5,051
06-09-26 조회 5,295
06-09-26 조회 5,414
06-09-22 조회 4,247
06-09-21 조회 3,532
06-09-21 조회 3,616
06-09-02 조회 3,473
06-08-08 조회 5,105
06-07-20 조회 3,705
06-07-17 조회 3,337
06-07-13 조회 4,157
06-07-11 조회 3,452
06-07-11 조회 3,451
06-07-11 조회 3,823
06-06-29 조회 6,038
06-06-19 조회 6,438
06-06-02 조회 3,490
06-05-24 조회 4,979
06-05-14 조회 7,755
06-05-08 조회 3,868
06-02-02 조회 5,443
05-12-16 조회 4,490
05-12-05 조회 5,143
05-06-28 조회 4,092
05-04-11 조회 4,043
05-04-11 조회 4,237
05-04-11 조회 3,302
05-03-13 조회 3,207
05-03-12 조회 4,290
04-12-08 조회 7,766
04-12-01 조회 5,169
04-11-28 조회 3,324
04-11-28 조회 3,171
04-08-05 조회 5,597
04-08-05 조회 4,942
04-08-05 조회 5,540