[썸네일 생성]리스트 스킨 같은 곳에서 중복되지 않으면서 빠르게 썸네일 출력 > 그누4 팁자료실

그누4 팁자료실

그누보드4와 관련된 팁을 여러분들과 함께 공유하세요.
나누면 즐거움이 커집니다.

[썸네일 생성]리스트 스킨 같은 곳에서 중복되지 않으면서 빠르게 썸네일 출력 정보

[썸네일 생성]리스트 스킨 같은 곳에서 중복되지 않으면서 빠르게 썸네일 출력

본문

### 그누폐인님의 요청에 따라 기능을 보강하여 원본을 수정하였습니다.
### 추가된 옵션 $copy_rule 값이 비엇거나 width이면 너비를 기준으로 하여 정렬합니다.
### 추가된 옵션 $copy_rule 값이 height이면 높이를 기준으로 하여 정렬합니다.
### 추가된 옵션 $copy_pos 값이 비엇거나 1이면 원본이미지의 왼쪽이나 상단을 기준으로 정렬합니다.
### 추가된 옵션 $copy_pos 값이2이면 원본이미지의 중앙을 기준으로 정렬합니다.
### 추가된 옵션 $copy_pos 값이3이면 원본이미지의 오른쪽이나 하단을 기준으로 정렬합니다.
### 추가된 옵션 $copy_pos 값이4이면 원본이미지와 같은 비율로 썸네일을 생성합니다.


리스트 스킨 같은 곳에서 이미지 썸네일을 쉽게 만들고 보여주는 방법입니다.
이미 썸네일이 만들어져 있으면 재작업을 하지 않으며,
크기에 따른 개별적 썸네일을 만들수 있으며,
썸네일끼리 영향을 받지 않으며,
브라우져 캐쉬에도 영향을 받지 않습니다.

lib 디렉토리 내의 적당한 라이브러리 파일에 다음 두 함수를 추가합니다.

//원본이미지의 경로, 크기, 높이, 타입을 알 경우에 사용가능
function make_smallimg ($src, $src_w, $src_h, $src_t, $copy, $copy_w, $copy_h, $copy_rule='width', $copy_pos='1'){

  if ($src_t == 1)
    $src = @imagecreatefromgif($src);
  else if ($src_t == 2)
    $src = @imagecreatefromjpeg($src);
  else if ($src_t == 3)
    $src = @imagecreatefrompng($src);
  else
    return false;

  if (empty($src)) return false;
  if (empty($copy) || $copy_w < 10 || $copy_h < 10) return false;

  $src_x = 0;
  $src_y = 0;
  $copy_x = 0;
  $copy_y = 0;

  if ($copy_rule == 'width' || empty($copy_rule)) {//너비에 맞춤

    $rate = $src_h / $src_w;
    $new_w = $copy_w;
    $new_h = (int) ($rate * $copy_w);

    if ($new_h < $copy_h){//만들어질 썸네일 높이가 비율대로 줄여진 높이보다 클경우 가운데 위치시킴

      if ($copy_pos != 4) $copy_y = (int) (($copy_h - $new_h) / 2);
      else $copy_h = $new_h;//비율대로
    }
    else {

      if ($copy_pos == '1' || empty($copy_pos)) {//원본에서 상단을 기준으로 가져옴

        //기본값 그대로
      }
      else if ($copy_pos == '2') {//원본에서 중앙을 기준으로 가져옴

        $temp_h = (int) ($copy_h / $copy_w * $src_w);
        $src_y = (int) (($src_h - $temp_h) / 2);
      }
      else if ($copy_pos == '3') {//원본에서 하단을 기준으로 가져옴

        $temp_h = (int) ($copy_h / $copy_w * $src_w);
        $src_y = $src_h - $temp_h;
      }
      else if ($copy_pos == '4') {//비율대로

        $copy_h = $new_h;
      }
    }
  }
  else {//높이에 맞춤

    $rate = $src_w / $src_h;
    $new_h = $copy_h;
    $new_w = (int) ($rate * $copy_h);

    if ($new_w < $copy_w){//만들어질 썸네일 너비가 비율대로 줄여진 너비보다 클경우 가운데 위치시킴

      if ($copy_pos != 4) $copy_x = (int) (($copy_w - $new_w) / 2); 
      else $copy_w = $new_w;//비율대로
    }
    else {

      if ($copy_pos == '1' || empty($copy_pos)) {//원본에서 왼쪽을 기준으로 가져옴

        //기본값 그대로
      }
      else if ($copy_pos == '2') {//원본에서 중앙을 기준으로 가져옴

        $temp_w = (int) ($copy_w / $copy_h * $src_h);
        $src_x = (int) (($src_w - $temp_w) / 2);
      }
      else if ($copy_pos == '3') {//원본에서 오른쪽을 기준으로 가져옴

        $temp_w = (int) ($copy_w / $copy_h * $src_h);
        $src_x = $src_w - $temp_w;
      }
      else if ($copy_pos == '4') {//비율대로

        $copy_w = $new_w;
      }
    }
  }

  $dst = @imagecreatetruecolor($copy_w, $copy_h);
  if (empty($dst)) return false;

  $background_color = @imagecolorallocate($dst, 255, 255, 255);
  if (empty($background_color)) return false;

  imagefilledrectangle($dst, 0, 0, $copy_w, $copy_h, $background_color);   
  imagecopyresampled($dst, $src, $copy_x, $copy_y, $src_x, $src_y, $new_w, $new_h, $src_w, $src_h);

  imagepng($dst, $copy);
  chmod($copy, 0606);
  return true;
}

//리스트스킨에서 썸네일을 보여줄때 사용
function get_smallimg_in_list($bo_table, $file, $num, $w, $h, $error_img, $style='', $copy_rule='width', $copy_pos='1'){

  global $g4;

  $temp_origine_img = "$g4[path]/data/file/$bo_table/" . urlencode($file[$num]['file']);

  if (empty($bo_table) || empty($file[$num]) || !is_file($temp_origine_img) || $w < 10 || $h < 10) {

    $temp_small = false;
  }
  else {

    if (empty($file[$num]['image_width']) || empty($file[$num]['image_height']) || empty($file[$num]['image_type'])) {

      $temp = getimagesize($temp_origine_img);
      $temp_origine_img_w = $temp[0];
      $temp_origine_img_h = $temp[1];
      $temp_origine_img_t = $temp[2];
    }
    else {

      $temp_origine_img_w = $file[$num]['image_width'];
      $temp_origine_img_h = $file[$num]['image_height'];
      $temp_origine_img_t = $file[$num]['image_type'];
    }

    $temp_small_img_w = $w;
    $temp_small_img_h = $h;
    $temp_small_dir = "$g4[path]/data/file/$bo_table/smallimg";

    if (!is_dir($temp_small_dir)){

      mkdir($temp_small_dir) or die('썸네일을 저장할 디렉토리를 생성할수 없습니다.');
    }

    $temp_small_img = "$temp_small_dir/s_{$temp_small_img_w}_{$temp_small_img_h}_" . urlencode($file[$num][file]);

    if (is_file($temp_origine_img) && !is_file($temp_small_img)) {

      $temp_small = make_smallimg ($temp_origine_img, $temp_origine_img_w, $temp_origine_img_h, $temp_origine_img_t, $temp_small_img, $temp_small_img_w, $temp_small_img_h, $copy_rule, $copy_pos);
    }
    else if (is_file($temp_origine_img) && is_file($temp_small_img)){

      $temp_small = true;
    }
    else {

      $temp_small = false;
    }
  }

  if ($temp_small) {

    return "<img src='$temp_small_img' width='$temp_small_img_w' height='$temp_small_img_h' border=0 $style onError=\"this.src='$error_img';\">";
  }
  else {

    return "<img src='$error_img' width='$w' height='$h' border=0 $style>";
  }
}


그리고 해당 리스트 스킨에서

for ($i=0; $i<count($list); $i++) {

아래에 적당한 위치에 이미지를 출력할 부분에

아래와 같이 넣으면 됩니다.

<?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 0, 75, 50, '/img/errorimg.gif', 'style="border:1px solid #000000;"', 'width', '1')?>

위에서 0, 75, 50, '/img/errorimg.gif', 'width', '1' 부분만 설명하면(나머진 그대로 하면 됩니다.)
0은 업로드 된 이미지중 몇번째 것을 썸네일로 보여줄것인지 지정합니다. 0, 1, 2, 3, 4 등이 올수 있습니다.
75는 만들어질 썸네일을 너비 입니다.
50은 만들어질 썸네일의 높이 입니다.
'/img/errorimg.gif' 은 이미지가 없거나 썸네일 생성 실패시 대신 보여줄 이미지 입니다.
'width' 는 너비와 높이중 어느것을 기준으로 할것인지 지정한것입니다. 썸네일로 보여질 모양이 너비가 길면' width', 높이가 길면 'height'로 하는 것이 좋습니다.
'1' 만들어질 썸네일의 비율보다 높이나 너비가 클경우 어느 부분을 짤라올것인지 결정합니다. '1'은 왼쪽이나 상단, '2'는 중앙, '3'은 오른쪽이나 하단을 기준으로 잘라옵니다. '4' 는 정비율 그대로 축소하여 보여줍니다.

추천
10

댓글 46개

네 코멘트 너무 빠르네요

이것은 원본 이미지를 삭제하더라도
썸네일 삭제 부분을 추가하지 않아도 됩니다.
기본적으로 원본 파일이 존재하지 않으면 기존에 만들어놓은 썸네일이 있다고 하더라도
출력되지 않습니다.

일반적으로 썸네일의 용량은 크게 걱정되는 부분은 아닌데
그래도 염려가 되는 분들은
해당 썸네일이 생성되는 경로를 정기적으로
지워주는 부분을 만들어줘도 되겠습니다.
감사합니다.

여담입니다.
이거 기존 갤러리나 이런것들 만들때도 편할수 있습니다.
지금 갤러리 스킨들 보면 여분 필드를 사용하는 것이 공식처럼 되어있는데
반듯이 여분 필드를 사용할 필요가 없습니다.

리스트 스킨에서 간단하게 출력하고 싶은 크리로 넣어주기만 하면 됩니다.

만약 게시판마다 썸네일의 크기가 달라야 한다면
스킨복사본을 만들고 이름을
해당스킨명_사이즈w_사이즈h 이렇게 사용하면 됩니다.

여분필드를 사용하지 않을때의 장점은
사용하다가 게시판 스킨의 변경이 용이합니다.
lib 디렉토리 내의 적당한 라이브러리 파일에 다음 두 함수를 추가합니다///

답: common.lib.php 의 맨하단에 삽입하였습니다..

그리고..
그리고 해당 리스트 스킨에서 

for ($i=0; $i<count($list); $i++) { 

아래에 적당한 위치에 이미지를 출력할 부분에

아래와 같이 넣으면 됩니다.

<?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 1, 75, 50, '/img/errorimg.gif', 'style="border:1px solid #000000;"')?>

라고해서..
basic 스킨의 list.skin.php 에서

<? for ($i=0; $i<count($list); $i++) { ?>
<?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 1, 75, 50, '/img/errorimg.gif', 'style="border:1px solid #000000;"')?>

처럼했는데...썸네일이 생성이 안되네요...
잘 될텐데요

지금 색시별님이 적용하신것은
두번째 이미지를 썸네일로 보여주는것입니다.
첫번째 이미지를 보여주고 싶으시면
<?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 0, 75, 50, '/img/errorimg.gif', 'style="border:1px solid #000000;"')?> 
요렇게 해주시면 됩니다.
1대신 0을 집어넣으세요.
그리고 이미지가 없거나 에러시에 보여질 이미지경로는 자신에 맞는 이미지 url로 넣으세요
유창화님 감사합니다..쪽지까지 날려주시고...

아주 잘되네요...

몇번째 이미지를 썸네일로 보여줄 것이가를 간과했군요..

그런데..제가 좀 초보라 그러는데요..
썸네일을 클릭하면 이미지를 새창으로 출력하거나..본문 글읽기로 가게하려면 어찌하면 되나요..
단순히 본문으로 가게 하기 위해선

<a href='<?=$list[$i][href]?>' <?=$style?>><?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 0, 75, 50, '/img/errorimg.gif', 'style="border:1px solid #000000;"')?></a>

요렇게만 해주면 됩니다.

그리고 이미지 보기창을 사용할려면 조금은 복잡한데요

해당 스킨에 아래 스크립트를 그대로 복사해서 넣습니다.

<script language="JavaScript">
//기존 image_window를 이미지 정보로서 사용되도록 조금 수정한것입니다
//이미지 url, 이미지 너비, 이미지 높이
function image_window_with_info(img_url, img_w, img_h)
{
    var w = img_w;
    var h = img_h;
    var winl = (screen.width-w)/2;
    var wint = (screen.height-h)/3;

    if (!img_url || !img_w || !img_h){

      return;
    }

    if (w >= screen.width) {
        winl = 0;
        h = (parseInt)(w * (h / w));
    }

    if (h >= screen.height) {
        wint = 0;
        w = (parseInt)(h * (w / h));
    }

    var js_url = "<script language='JavaScript1.2'> \n";
        js_url += "<!-- \n";
        js_url += "var ie=document.all; \n";
        js_url += "var nn6=document.getElementById&&!document.all; \n";
        js_url += "var isdrag=false; \n";
        js_url += "var x,y; \n";
        js_url += "var dobj; \n";
        js_url += "function movemouse(e) \n";
        js_url += "{ \n";
        js_url += "  if (isdrag) \n";
        js_url += "  { \n";
        js_url += "    dobj.style.left = nn6 ? tx + e.clientX - x : tx + event.clientX - x; \n";
        js_url += "    dobj.style.top  = nn6 ? ty + e.clientY - y : ty + event.clientY - y; \n";
        js_url += "    return false; \n";
        js_url += "  } \n";
        js_url += "} \n";
        js_url += "function selectmouse(e) \n";
        js_url += "{ \n";
        js_url += "  var fobj      = nn6 ? e.target : event.srcElement; \n";
        js_url += "  var topelement = nn6 ? 'HTML' : 'BODY'; \n";
        js_url += "  while (fobj.tagName != topelement && fobj.className != 'dragme') \n";
        js_url += "  { \n";
        js_url += "    fobj = nn6 ? fobj.parentNode : fobj.parentElement; \n";
        js_url += "  } \n";
        js_url += "  if (fobj.className=='dragme') \n";
        js_url += "  { \n";
        js_url += "    isdrag = true; \n";
        js_url += "    dobj = fobj; \n";
        js_url += "    tx = parseInt(dobj.style.left+0); \n";
        js_url += "    ty = parseInt(dobj.style.top+0); \n";
        js_url += "    x = nn6 ? e.clientX : event.clientX; \n";
        js_url += "    y = nn6 ? e.clientY : event.clientY; \n";
        js_url += "    document.onmousemove=movemouse; \n";
        js_url += "    return false; \n";
        js_url += "  } \n";
        js_url += "} \n";
        js_url += "document.onmousedown=selectmouse; \n";
        js_url += "document.onmouseup=new Function('isdrag=false'); \n";
        js_url += "//--> \n";
        js_url += "</"+"script> \n";

    var settings;

    if (g4_is_gecko) {
        settings  ='width='+(w+10)+',';
        settings +='height='+(h+10)+',';
    } else {
        settings  ='width='+w+',';
        settings +='height='+h+',';
    }
    settings +='top='+wint+',';
    settings +='left='+winl+',';
    settings +='scrollbars=no,';
    settings +='resizable=yes,';
    settings +='status=no';


    win=window.open("","image_window",settings);
    win.document.open();
    win.document.write ("<html><head> \n<meta http-equiv='imagetoolbar' CONTENT='no'> \n<meta http-equiv='content-type' content='text/html; charset="+g4_charset+"'>\n");
    var size = "이미지 사이즈 : "+w+" x "+h;
    win.document.write ("<title>"+size+"</title> \n");
    if(w >= screen.width || h >= screen.height) {
        win.document.write (js_url);
        var click = "ondblclick='window.close();' style='cursor:move' title=' "+size+" \n\n 이미지 사이즈가 화면보다 큽니다. \n 왼쪽 버튼을 클릭한 후 마우스를 움직여서 보세요. \n\n 더블 클릭하면 닫혀요. '";
    }
    else
        var click = "onclick='window.close();' style='cursor:pointer' title=' "+size+" \n\n 클릭하면 닫혀요. '";
    win.document.write ("<style>.dragme{position:relative;}</style> \n");
    win.document.write ("</head> \n\n");
    win.document.write ("<body leftmargin=0 topmargin=0 bgcolor=#dddddd style='cursor:arrow;'> \n");
    win.document.write ("<table width=100% height=100% cellpadding=0 cellspacing=0><tr><td align=center valign=middle><img src='"+img_url+"' width='"+w+"' height='"+h+"' border=0 class='dragme' "+click+"></td></tr></table>");
    win.document.write ("</body></html>");
    win.document.close();

    if(parseInt(navigator.appVersion) >= 4){win.window.focus();}
}
</script>

그런다음 이미지 출력하는 부분에
아래내용을 복사해넣고
적당히 값을 수정해서 사용하시면 됩니다.

      <?

        $temp_num = 1;//몇번째 이미지를 사용할것인가 0, 1, 2, 3, 4 중하나
        $temp_copy_w = 75;//썸네일 너비
        $temp_copy_h = 50;//썸네일 높이
        $temp_error_img = 'http://8bong.com/skin/board/gallery/img/noimage.gif';
        $temp_style = " style=\"cursor:pointer; border:1px solid #000000;\"";
        $temp_copy_rule = 'width';
        $temp_copy_pos = '1';

        //이하 수정할 필요없습니다. 변수명이 복잡하여 줄인것 뿐입니다.
        $temp_img_w = $list[$i]['file'][$temp_num]['image_width'];
        $temp_img_h = $list[$i]['file'][$temp_num]['image_height'];
        $temp_img_url = $list[$i]['file'][$temp_num]['path'] . '/' . $list[$i]['file'][$temp_num]['file'];
        $temp_style .= " onclick=\"image_window_with_info('$temp_img_url', '$temp_img_w', '$temp_img_h');\"";

        echo get_smallimg_in_list($bo_table, $list[$i]['file'], $temp_num, $temp_copy_w, $temp_copy_h, $temp_error_img, $temp_style, $temp_copy_rule, $temp_copy_pos);
         
      ?>
유창화님//아주 감사합니다..

제가 어디좀 갔다오느라고 친절하게도 쪽지를 주신것을 이제사 읽었습니다...

그리고 아주 잘됩니다... 아주 좋아요..
저는 드림퀘스트 섬브네일엔진을 쓰고 있는데요. 이 엔진에서 리사이즈방식이 옵션으로 3개가 있는데 그중에 원본비율리사이즈를 하면서도 Center Crop이 되는게 상당히 편리하더군요. 유창화님의 소스에서도 이 기능이 지원이 된다면 금상첨화겠습니다.
해당기능을 추가하여 원글을 수정하였습니다.

해당 함수들과 사용법을 다시 한번 보시고

새로 복사해 가시기 바랍니다.
작업중인 웹진 스킨에 적용해보았습니다.
crop 기능이 필요한 경우 매우 유용하게 사용될것 같습니다.
이전에 만들어주신 외부 이미지 썸네일 생성기능과 일관되게 쓰기위해서 테스트만 해보고 실제 적용은 안합니다만,
기회가 된다면 꼭 활용해보고 싶은 부분입니다.

외부 이미지 썸네일 관련 스킨작업은 거의 완성된듯 합니다.
업데이트나 리스트에서의 처리도 만족스럽게 되었고 일괄처리 부분만 팝업으로 처리하도록 했습니다.
팝업이 아닌 iframe으로 처리가 가능한지 좀더 찾아보고 마무리하면 될듯 합니다.
꼼꼼히 챙겨주셔서 거듭 감사의 말씀 올립니다.
휴일에도 지켜보고 계신듯 합니다.^^
일괄처리 링크를 팝업으로 띄우지 않고 히든프레임으로 가능하군요.
이 역시 유창화님 코드와 오달수님스크립트를 원용해서 간단히 해결했습니다.ㅎㅎ
테스트 링크 권한을 풀어놓겠습니다.
http://gnusr.com/g4/bbs/board.php?bo_table=webzin_edit
시간되시면 테스트 부탁드립니다.
썸네일을 만들로 리스트 출력하는 함수를 common.lib.php 에 삽입하니 잘되는데..

혹시 썸네일을 만들기 위한 lib.php를 별도로 만들려면 어찌하면 되나요..

원본에 새로운 코드를 넣으니 업데이트시에 좀..아주쬠끔 불편할듯 해서요..
그렇게 해도 됩니다.

해당 리스트 스킨 젤 상단에

include_once("$g4[path]/lib/해당파일명");

이렇게 추가해주면 되겟지요
업그레이드가 되었네요.

제가 요즈음 진행중인 작업때문에 아직 테스트도 못해보고 있습니다.

마무리되는 즉시 업어다가 요리 할렵니다.ㅎㅎ^^
유창화님!!!
디큐섬네일기능을 사용하면서 느낀 점이 좀 무겁게 돌아간다는 느끼김을 받는데요...
저같은 무지한 사람들 사용하기에는 디큐가 간단하다는 생각도 해보았습니다.
사용원리가 비슷하겠지만 습관인지도 모릅니다.

죄송하지만 유창화님의 썸네일기능과 디큐썸네일기능을 비교해주실 수 있으시면 부탁드립니다.
글세요 제가 그걸 보지 못해서 머라 드릴말씀은 없구요

기능적으로 큰 차이는 없지 않을 까 싶습니다.

그것보단

스킨같은곳에 좀 더 쉽게 적용할수 있도록 함수를 만들었다는 정도가 장점입니다.
좋은 내용입니다.  매우 응용범위가 넓어지겠다는 생각입니다.
여분필드를 사용하지 않아도 된다는 것이 매우 마음에 드네요..  연구 연구..
겁나 좋은 소스 입니다.

계속 안되던데 제가 허접하다보니..

이제 정말 잘되네요.. 와우와우.. 감탄사만 나올뿐입니다.
유창화님, 항상 소스 너무너무 잘 보고있습니다.
정말 너무 좋은 소스들을 공개해주셔서 정말로 감사하게 생각하고 있습니다.

그런데, 사진이 있는 게시물은 썸네일이 나와서 이쁜데...
사진이 없는 게시물은 썸네일이 엑박으로 표시되서 조금 보기가 안좋은데요..

사진이 있으면 기존처럼 썸네일이 나오고...
사진이 없는 게시물은 그냥 썸네일 없이 제목만 나오도록 하려면... 
알려주셨던 아래 출력소스 부분에서, 어디를 고치면 되는지......

<a href='<?=$list[$i][href]?>' <?=$style?>><?=get_smallimg_in_list($board['bo_table'], $list[$i]['file'], 0, 60, 50, '/img/errorimg.gif', 'style="border:1px solid #999999;"')?></a>

항상 다른 분들을 위해 소스 공개해주셔서 너무 감사드립니다.
언제나 좋은 나날들 행복한 날들 되세요^^ (꾸벅)
전체 46 |RSS
그누4 팁자료실 내용 검색
  • 개별 목록 구성 번호 제목 작성자 작성일 추천 조회
  • 게시물이 없습니다.

회원로그인

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