유

워터마크 함수 기능 보강 및 종합 썸네일함수 버그 수정

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

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

워터마크 함수 기능 보강 및 종합 썸네일함수 버그 수정

이전에는 종합 썸네일 함수를 만들어 보았습니다.
이번에는 워터마크 함수의 기능 보강과 종합 썸네일 함수의 버그을 수정해 보겠습니다.

기존 워터마크 함수는 투명 이미지는 사용할수 없었습니다.
이유는 선명도($sharpness) 때문입니다. 투명이미지 이기 때문에 선명도를 줄수 없기 때문입니다.
그래서 php의 내장함수인 imagecopymerge 는 불투명 이미지로 간주하고 이미지를 처리하기 때문에 투명 이미지를 사용할 경우에는 불투명 하게 제대로 워터마크 처리 되지 않았습니다.

좀 더 유연한 워터마크의 처리를 위해서 선명도가 100 일 경우에는 imagecopymerge 대신 imagecopyresampled 를 사용하여 투명이미지를 워터마크로 사용할수 있도록 처리하겠습니다.

예제1 : proc_watermark 수정

function proc_watermark($src, $src_w, $src_h, $path_mark_file, $pos, $sharpness, $padding=0){

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

    $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($sharpness)) settype($sharpness, 'int');
  if (!is_int($padding)) settype($padding, 'int');



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

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

    return false;
  }



  if (empty($path_mark_file)) {//워터마크 이미지 경로값이 없다면

    $GLOBALS['errormsg'] = '워터마크 이미지경로값이 없습니다.';

    return false;
  }

  list($mark, $mark_w, $mark_h) = get_image_resource_from_file ($path_mark_file);

  if (empty($mark)) return false;//에러 메시지 작성은 get_image_resource_from_file 내부에서 함



  if ($src_w < $mark_w + (2 * $padding)) {//원본너비가 워터마크 이미지 너비보다 작으면 워터마크 처리 안함, return true;

    return true;
  }

  if ($src_h < $mark_h + (2 * $padding)) {//원본높이가 워터마크 이미지 높이보다 작으면 워터마크 처리 안함, return true;

    return true;
  }



  if ($sharpness < 0 || $sharpness > 100) $sharpness = 30;//$sharpness 가 지정된 범위 이상의 숫자라면 30으로 강제 재설정

  if ($padding < 0 || $padding > $mark_w || $padding > $mark_h) $padding = 10;//$padding이 0보다 작거나 워터마크의 너비나 높이보다 크면 10으로 강제 재설정



  if ($pos == 10) {//워터마크 전체로 찍을 경우의 처리

    $w_max = $src_w - $padding;
    $h_max = $src_h - $padding;

    //x 축으로 워터마크를 몇번 찍을 것인지 계산, 패딩을 더해서 나눔
    $x_max = ceil($w_max / ($mark_w + $padding));

    //y 축으로 워터마크를 몇번 찍을 것인지 계산
    $y_max = ceil($h_max / ($mark_h + $padding));

    //루프를 돌리면서 워터마크를 찍음
    for($x = 0; $x < $x_max; $x++){

      for($y = 0; $y < $y_max; $y++){

        //기준점을 구한다.
        $src_x = $x * ($mark_w + $padding) + $padding;
        $src_y = $y * ($mark_h + $padding) + $padding;

        $copy_w = $mark_w;
        $copy_h = $mark_h;

        if ($src_x + $mark_w > $w_max) $copy_w = $w_max - $src_x;
        if ($src_y + $mark_h > $h_max) $copy_h = $h_max - $src_y;

        if ($sharpness != 100) {//선명도가 100 이 아닐경우에는 선명도를 사용할수 있는 imagecopymerge 사용

          $result_watermark = imagecopymerge($src, $mark, $src_x, $src_y, 0, 0, $copy_w, $copy_h, $sharpness);
        }
        else {//선명도가 100 일 경우에는 투명이미지를 사용할수 있는 imagecopyresampled 사용

          $result_watermark = imagecopyresampled ($src , $mark , $src_x, $src_y, 0 , 0 , $copy_w, $copy_h , $copy_w, $copy_h);
        }

        if ($result_watermark === false) {

          @imagedestroy($mark);

          $GLOBALS['errormsg'] = "워터마크 처리에 실패하였습니다.";

          return false;
        }
      }
    }
  }
  else {//워터마크를 하나만 찍을 경우에의 처리

    //워터마크의 복사할 너비, 높이 기본값 지정
    $copy_w = $mark_w;
    $copy_h = $mark_h;

    switch($pos){

      case 1 : //상단 왼쪽

        $src_x = 0 + $padding;
        $src_y = 0 + $padding;

        break;

      case 2 : //상단 오른쪽

        $src_x = $src_w - $mark_w - $padding;
        $src_y = 0 + $padding;

        break;

      case 3 : //하단 왼쪽

        $src_x = 0 + $padding;
        $src_y = $src_h - $mark_h - $padding;

        break;

      case 4 : //하단 오른쪽

        $src_x = $src_w - $mark_w - $padding;
        $src_y = $src_h - $mark_h - $padding;

        break;

      case 5 : //중앙

        $src_x = ceil(($src_w - $mark_w) / 2);
        $src_y = ceil(($src_h - $mark_h) / 2);

        break;

      default : // 그 밖의 값은 전부 상단 왼쪽 치부

        $src_x = 0 + $padding;
        $src_y = 0 + $padding;

    }

    if ($sharpness != 100) {//선명도가 100 이 아닐경우에는 선명도를 사용할수 있는 imagecopymerge 사용

      $result_watermark = imagecopymerge($src, $mark, $src_x, $src_y, 0, 0, $copy_w, $copy_h, $sharpness);
    }
    else {//선명도가 100 일 경우에는 투명이미지를 사용할수 있는 imagecopyresampled 사용

      $result_watermark = imagecopyresampled ($src , $mark , $src_x, $src_y, 0 , 0 , $copy_w, $copy_h , $copy_w, $copy_h);
    }

    @imagedestroy($mark);

    if ($result_watermark === false) {

      $GLOBALS['errormsg'] = "워터마크 처리에 실패하였습니다.";

      return false;
    }
  }

  return true;
}


이전시간에 만들어 보았던 종합 썸네일 테스트 함수인 thumnail_test1 은 약간의 버그가 있었습니다.
버그의 내용은 썸네일의 너비와 높이중 둘중 하나의 값이 0 일경우 내부적으로 정비율로 리사이즈하는 부분이 있는데, 리사이즈후 계산된 너비와 높이를 받아오지 않아서 워터마크가 작동하지 않는 부분이 있었습니다. 리사이즈나 크롭을 처리한후에 생성된 썸네일의 리소스로부터 다시 실제 너비와 높이를 받아오는 부분을 넣음으로서 이 버그를 해결 하였습니다.

예제2 : thumnail_test1 수정

function thumnail_test1($path_src_file, $path_save_file, $save_w, $save_h=0, $options=Array()){

  //기본값 설정
  $save_quality = 70;//저장 품질 : 70 %
  $save_force = 2;//저장형태 : 파일 덮어씌움

  $crop_use = 0;//크롭 사용여부
  $crop_pos_width = 2;//너비 기준 크롭시 중앙을 기준
  $crop_pos_height = 1;//높이 기준 크롭시 상단을 기준

  $watermark_path_file = '';//워터마크로 사용할 파일 경로 : 없음
  $watermark_pos = 4;//워터마크 찍는 위치 : 하단 오른쪽
  $watermark_sharpness = 30;//워터마크 이미지의 선명도 : 30 %
  $watermark_padding = 10;//원본과 워터마크 사이의 여백 : 10px

  //기본값 재설정
  if (!empty($options)) @extract($options);

  //원본 리소스 생성
  list($src, $src_w, $src_h) = get_image_resource_from_file ($path_src_file);
  if (empty($src)) return false;

  //리사이즈 또는 크롭 리사이즈
  if ($crop_use == 1) {//크롭 리사이즈

    $dst = get_image_cropresize($src, $src_w, $src_h, $save_w, $save_h, $crop_pos_width, $crop_pos_height);
  }
  else {//리사이즈

    $dst = get_image_resize($src, $src_w, $src_h, $save_w, $save_h);
  }

  @imagedestroy($src);
  if (empty($dst)) return false;

  $save_w = imagesx($dst);//생성된 썸네일 리소스에서 실제 너비를 구한다.
  $save_h = imagesy($dst);//생성된 썸네일 리소스에서 실제 높이를 구한다.

  //워터마크 이미지가 파일일 경우, 워터마크 처리
  if (!empty($watermark_path_file) && is_file($watermark_path_file)) {

    $result_watermark = proc_watermark($dst, $save_w, $save_h, $watermark_path_file, $watermark_pos, $watermark_sharpness, $watermark_padding);

    if (empty($result_watermark)) return false;
  }

  $result_save = save_image_from_resource ($dst, $path_save_file, $save_quality, $save_force);

  @imagedestroy($dst);

  return $result_save;
}

썸네일 리소스로부터 실제 너비와 높이를 구할때 imagesx 와 imagesy php 내장함수가 사용되었습니다.
이 두 함수는 각각 이미지 리소스로 부터 너비와 높이를 구해주는 함수입니다.


다음 예제를 통해 투명이미지의 워터마크 사용과 불투명 이미지의 워터마크 사용을 처리해 보도록 하겠습니다.

예제3 : test17.php

<?php

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



$path_src_file = 'sample_image/test.jpg';//원본파일
$path_mark_file1 ='sample_image/php.png';//워터마크에 사용할 파일, 불투명
$path_mark_file2 ='sample_image/noback.png';//워터마크에 사용할 파일, 투명

$path_400X0_file = 'sample_image/test_400X0.jpg';//원본파일을 너비 400으로 정비율 리사이즈



//원본을 너비 400 정비율 리사이즈, $path_400X0_file 에 기본 저장 옵션
$save_w = 400;

$result = thumnail_test1($path_src_file, $path_400X0_file, $save_w);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
너비 $save_w 으로 정비율 리사이즈 <br />
<img src='$path_400X0_file'> <br /><br />
";
flush();



//$path_400X0_file을 너비 300 정비율 리사이즈, 불투명 워터마크 사용
$save_w = 300;
$save_h = 0;

$options = Array();//옵션설정

$options['watermark_path_file'] = $path_mark_file1;//워터마크 이미지
$options['watermark_sharpness'] = 50;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_1.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
너비 $save_w 으로 정비율 리사이즈, 불투명 워터마크 사용 <br />
<img src='$path_save_file'> <br /><br />
";
flush();



//$path_400X0_file을 너비 300 정비율 리사이즈, 투명 워터마크 사용
$save_w = 300;
$save_h = 0;

$options = Array();//옵션설정

$options['watermark_path_file'] = $path_mark_file2;//워터마크 이미지
$options['watermark_sharpness'] = 100;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_2.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
너비 $save_w 으로 정비율 리사이즈, 투명 워터마크 사용 <br />
<img src='$path_save_file'> <br /><br />
";
flush();



//$path_400X0_file을 높이 300 정비율 리사이즈, 불투명 워터마크 사용
$save_w = 0;
$save_h = 300;

$options = Array();//옵션설정

$options['watermark_path_file'] = $path_mark_file1;//워터마크 이미지
$options['watermark_sharpness'] = 50;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_1.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
높이 $save_h 으로 정비율 리사이즈, 불투명 워터마크 사용 <br />
<img src='$path_save_file'> <br /><br />
";
flush();



//$path_400X0_file을 높이 300 정비율 리사이즈, 투명 워터마크 사용
$save_w = 0;
$save_h = 300;

$options = Array();//옵션설정

$options['watermark_path_file'] = $path_mark_file2;//워터마크 이미지
$options['watermark_sharpness'] = 100;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_2.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
높이 $save_h 으로 정비율 리사이즈, 투명 워터마크 사용 <br />
<img src='$path_save_file'> <br /><br />
";
flush();



//$path_400X0_file을 너비 300, 높이 300 강제 리사이즈, 불투명 워터마크 사용
$save_w = 300;
$save_h = 300;

$options = Array();//기본옵션
$options['watermark_path_file'] = $path_mark_file1;//워터마크 이미지
$options['watermark_sharpness'] = 50;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_1.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
너비 $save_w, 높이 $save_h 강제 리사이즈 <br />
<img src='$path_save_file'> <br /><br />
";
flush();



//$path_400X0_file을 너비 300, 높이 300 강제 리사이즈, 투명 워터마크 사용
$save_w = 300;
$save_h = 300;

$options = Array();//기본옵션
$options['watermark_path_file'] = $path_mark_file2;//워터마크 이미지
$options['watermark_sharpness'] = 100;
$options['watermark_pos'] = 10;

$path_save_file = 'sample_image/test_' . $save_w . 'X' . $save_h . '_2.jpg';

$result = thumnail_test1($path_400X0_file, $path_save_file, $save_w, $save_h, $options);
if (empty($result)) die($GLOBALS['errormsg'] . "<br />\n");

echo "
너비 $save_w, 높이 $save_h 강제 리사이즈 <br />
<img src='$path_save_file'> <br /><br />
";
flush();

?>

사용자 삽입 이미지사용자 삽입 이미지

첨부파일

image_proc.function.php (24 KB) 77회 2013-01-14 16:19
|

댓글 3개

네에 고맙습니다.
댓글을 작성하시려면 로그인이 필요합니다.

프로그램

8,188건
+
제목 글쓴이 날짜 조회
15-12-13 조회 2,530
15-12-13 조회 2,945
15-12-11 조회 2,606
15-12-11 조회 2,566
15-12-11 조회 2,570
15-12-10 조회 2,528
15-12-10 조회 2,587
15-12-10 조회 2,560
15-12-03 조회 3,203
15-12-03 조회 2,718
15-11-25 조회 2,800
15-11-09 조회 3,209
15-11-04 조회 2,971
15-06-09 조회 4,095
15-05-06 조회 5,093
15-03-28 조회 4,576
14-12-05 조회 4,999
14-10-25 조회 5,097
14-10-13 조회 4,273
14-10-03 조회 6,262
14-09-19 조회 4,964
14-09-18 조회 4,050
14-09-13 조회 4,615
14-09-03 조회 5,602
14-08-26 조회 4,210
14-08-26 조회 4,013
14-08-26 조회 3,979
14-08-11 조회 6,506
14-08-06 조회 4,126
14-08-06 조회 3,724
14-08-06 조회 3,938
14-08-01 조회 6,306
14-08-01 조회 3,843
14-07-30 조회 4,443
14-06-28 조회 5,167
14-06-28 조회 4,438
14-05-11 조회 4,592
14-05-09 조회 4,950
14-05-09 조회 7,713
14-04-30 조회 4,336
14-04-27 조회 4,197
14-04-25 조회 4,899
14-04-21 조회 3,878
14-04-21 조회 5,006
14-04-10 조회 4,604
14-04-01 조회 6,158
14-03-03 조회 3,533
14-02-25 조회 5,922
14-02-14 조회 5,196
14-02-13 조회 4,953
14-01-03 조회 4,445
13-12-06 조회 3,767
13-11-22 조회 5,522
13-11-18 조회 4,029
13-10-02 조회 4,448
13-10-02 조회 3,698
13-10-02 조회 3,962
13-10-02 조회 3,817
13-10-02 조회 4,183
13-09-16 조회 8,032
13-09-16 조회 5,397
13-08-18 조회 5,429
13-07-11 조회 4,111
13-07-10 조회 4,694
13-07-09 조회 4,732
13-07-09 조회 4,988
13-07-04 조회 4,487
13-07-04 조회 4,125
13-07-04 조회 4,239
13-07-01 조회 4,727
13-07-01 조회 4,560
13-07-01 조회 6,835
13-06-23 조회 4,382
13-06-05 조회 3,629
13-05-29 조회 4,870
13-05-10 조회 4,276
13-04-05 조회 4,898
13-04-05 조회 6,586
13-04-05 조회 1.1만
13-04-05 조회 7,181
13-04-05 조회 6,567
13-03-31 조회 5,839
13-03-31 조회 4,166
13-03-28 조회 4,527
13-03-28 조회 6,724
13-03-28 조회 9,206
13-03-28 조회 4,338
13-03-24 조회 3,954
13-03-21 조회 4,631
13-03-21 조회 1.8만
13-03-14 조회 3,937
13-03-10 조회 4,746
13-03-10 조회 4,506
13-03-10 조회 4,207
13-03-08 조회 5,264
13-03-08 조회 4,370
13-03-03 조회 5,026
13-03-03 조회 7,480
13-03-03 조회 4,221
13-03-03 조회 1.1만