테스트 사이트 - 개발 중인 베타 버전입니다

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

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

강좌는 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();

?>

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

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 3개

감사합니다
네에 고맙습니다.
감사합니다.

게시글 목록

번호 제목
535
534
533
522
521
520
517
516
511
508
507
500
493
490
486
463
461
444
435
334
304
290
244
233
218
217
194
185
181
156