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

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

강좌는 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개

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

프로그램

태그 필터 (최대 3개) 전체 개발자 소스 기타 mysql 팁자료실 javascript php linux flash 정규표현식 jquery node.js mobile 웹서버 os 프로그램 강좌 썸네일 이미지관련 도로명주소 그누보드5 기획자 견적서 계약서 기획서 마케팅 제안서 seo 통계 서식 통계자료 퍼블리셔 html css 반응형 웹접근성 퍼블리싱 표준화 반응형웹 홈페이지기초 부트스트랩 angularjs 포럼 스크린리더 센스리더 개발자톡 개발자팁 퍼블리셔톡 퍼블리셔팁 기획자톡 기획자팁 프로그램강좌 퍼블리싱강좌
+
제목 글쓴이 날짜 조회
13년 전 조회 1,565
13년 전 조회 624
13년 전 조회 2,144
13년 전 조회 1,872
13년 전 조회 660
13년 전 조회 1,229
13년 전 조회 639
13년 전 조회 930
13년 전 조회 1,220
13년 전 조회 3,606
13년 전 조회 2,140
13년 전 조회 2,328
13년 전 조회 3,696
13년 전 조회 3,509
13년 전 조회 3,167
13년 전 조회 4,037
13년 전 조회 1,049
13년 전 조회 6,014
13년 전 조회 1,403
13년 전 조회 1,242
13년 전 조회 3,430
13년 전 조회 3,060
13년 전 조회 5,213
13년 전 조회 2,719
13년 전 조회 3,366
13년 전 조회 1,053
13년 전 조회 878
13년 전 조회 2,048
13년 전 조회 838
13년 전 조회 2,240
13년 전 조회 1,542
13년 전 조회 1,145
13년 전 조회 2,133
13년 전 조회 2,343
13년 전 조회 1,340
13년 전 조회 823
13년 전 조회 1,371
13년 전 조회 857
13년 전 조회 1,244
13년 전 조회 3,886
13년 전 조회 3,977
13년 전 조회 1,393
13년 전 조회 6,985
13년 전 조회 7,577
13년 전 조회 2,336
13년 전 조회 3,887
13년 전 조회 659
13년 전 조회 3,693
13년 전 조회 3,514
13년 전 조회 2,750
13년 전 조회 2,849
13년 전 조회 2,383
13년 전 조회 2,277
13년 전 조회 5,199
13년 전 조회 2,842
13년 전 조회 3,158
13년 전 조회 2,282
13년 전 조회 6,853
13년 전 조회 2,590
13년 전 조회 3,452
13년 전 조회 2,348
13년 전 조회 4,836
13년 전 조회 3,710
13년 전 조회 2,568
13년 전 조회 2,259
13년 전 조회 1,312
13년 전 조회 3,456
13년 전 조회 4,115
13년 전 조회 3,477
13년 전 조회 5,357
13년 전 조회 1,680
13년 전 조회 1,299
13년 전 조회 5,201
13년 전 조회 968
13년 전 조회 3,433
13년 전 조회 3,437
13년 전 조회 3,018
13년 전 조회 3,377
13년 전 조회 2,895
13년 전 조회 2,869
13년 전 조회 2,893
13년 전 조회 2,892
13년 전 조회 2,912
13년 전 조회 2,860
13년 전 조회 2,882
13년 전 조회 1,513
13년 전 조회 930
13년 전 조회 837
13년 전 조회 621
13년 전 조회 2,842
13년 전 조회 2,989
13년 전 조회 2,131
13년 전 조회 1,362
13년 전 조회 819
13년 전 조회 2,898
13년 전 조회 3,225
13년 전 조회 1,263
13년 전 조회 1.1만
13년 전 조회 1,446
13년 전 조회 462
🐛 버그신고