PHP

이미지 다루기

PHP를 이용해서 이미지를 프로그래밍적으로 생성하고 변경할 수 있다.

GD

이미지처리 작업은 PHP의 기본적인 기능에는 포함되어 있지 않다. 대신 라이브러리나 외부 프로그램과 연동을 해야 하는데 GD라이브러리가 가장 많이 사용된다.

GD의 설치

GD는 기본적으로 사용할 수 있도록 활성화 되어 있는 경우도 있고, 그렇지 않은 경우도 있다. 시스템의 현재 상황을 파악할 수 있는 방법은 phpinfo()를 실행해 보는 것이다. 아래 코드를 실행해보자.

<?php
phpinfo();
?>

출력 내용 중에서 특히 중요한 부분은 아래와 같다.

만약 gd가 보이지 않는다면 이를 활성화하거나 설치해야 한다.

php.ini 파일을 열어보고 아래와 같은 부분이 있는지 확인해보자. 만약 아래와 같다면 주석 ;를 제거해준다.

;extension=php_gd2.dll

윈도우 버전 Bitnami 사용자

윈도우 버전 bitnami를 사용하고 있다면 php.ini 파일에서 extension_dir 지시자의 값을 아래와 같이 변경해준다. 아래의 설정은 필자의 설정이기 때문에 자신에게 맞는 설정은 직접해주어야 한다.

extension_dir = "D:\BitNami\wampstack-5.4.21-0\php\ext"

리눅스

우분투처럼 apt-get을 사용할 수 있다면 아래와 같은 명령으로 gd를 설치 할 수 있다.

sudo apt-get install php5-gd;

예제

 

아래의 예제를 실행하기 위해서는 button.php과 같은 디렉토리에 button.png 파일이 존재해야 한다. 편의를 위해서 다음 이미지를 사용하자.

아래와 같이 접근하면 coding이라는 텍스트가 버튼에 표시될 것이다.

http://localhost/image/button.php?text=coding

코드는 아래와 같다.

<?php
header("Content-type: image/png");
$string = $_GET['text'];
$im     = imagecreatefrompng("button.png");
$orange = imagecolorallocate($im, 60, 87, 156);
$px     = (imagesx($im) - 7.5 * strlen($string)) / 2;
imagestring($im, 4, $px, 9, $string, $orange);
imagepng($im);
imagedestroy($im);
?>

아래의 예제는 위의 예제를 이용해서 버튼을 실시간으로 생성해주는 예제다.

<html>
<body>
    <img src="button.php?text=intro" />
	<img src="button.php?text=member" />
	<img src="button.php?text=history" />
	<img src="button.php?text=mission" />
</body>
</html>

실행결과는 아래와 같다.

예제2. 워터마크

 

이미지에 워터마크를 찍어보자. 아래에 3장의 이미지가 있다.

text.png

text.png

original.png

original.png

result.png

result.png

text.png를 original.png에 그려서 result.png를 만드는 것이 이번 예제의 목표다. 이를 위해서 text.png와 original.png를 /image 디렉토리에 복사해서 위치시키자.

<?php
// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('text.png');
$im = imagecreatefrompng('original.png');

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Copy the stamp image onto our photo using the margin offsets and the photo 
// width to calculate positioning of the stamp. 
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));

// Output and free memory
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);
?>

댓글

댓글 본문
작성자
비밀번호
  1. 덜렁이
    생활코딩이라는 text.png파일의 왼쪽 위
    대화보기
    • stool
      이미지가 두개 이므로 변수에 저장해야 할 듯
      대화보기
      • NamJin Kim
        감사합니다
      • enqn192
        마지막 예제에서 출력되는 사진은 어느 폴더에 저장이 되나요?
        어딘가 저장이 되었을 테니 출력이 되는 걸텐데 위치가 궁금하네요.
      • php.ini 수정했는데도 안된다고 하시는분들~~

        php.ini 는 수정후 꼭 아파치 웹서버를 restart 해주셔야 변경사항이 적용됩니다~~
      • 허민호
        안되시는분들 아파치 재실행 합시다 !!
      • JustStudy
        고맙습니다
      • 참빛바다
        만든 버튼을 파일로 저장 안하고 바로 워터마크로 쓰려면 어떻게 해야 할까요?
        $stamp = imagecreatefrompng('button.png');
        이 부분을 수정하면 될것 같긴 한데..
      • myusuch
        button.png 파일이 계속 깨져 나와서 이고잉님 코드랑 한줄 한줄 비교해봤더니
        헤더에 Content-type: image/png 에서
        Content-type과 콜론사이에 공백이 있으면 (Content-type : image/png)
        png그림이 깨집니다.. 그래서 공백을 지웠더니 정상적으로 그림이 나오는데 이유가 뭘까요??
      • 우어엉
        아파치를 재실행하셔야 합니다 -_-;;
      • 오잉
        이 부분은 그냥 개념만 한번 보고 지나가셔도 될 듯 싶네요~

        이해안되시는 분들 굳이 이 부분은 이해안해도 무방해 보입니다~
      • hasine1
        너무 감사하게 잘 듣고 있습니다.
        아래 질문이 있어서요~
        http://localhost......!
        한글글씨가 깨지는 것은 어떻게 고쳐야 하는지요?
      • 코딩!
        이러한 기능들이 있군요..
        실제 많이 쓰일려나요?
        포토샾으로 해서 사용하면 될것 같아요
      • phpinfo()로 gd확인 시 위와 같은 절차를 진행했음에도 나타나지 않아서 제가 수정해서 됬던 부분은 위의 extension_dir = 정의 부분에서 앞의 주석문을 지우지 않아서 안됬었습니다..
        extension=gd2.dll 주석 지우는 것처럼 위의 디렉토리 설정 부분의 주석도 지워주시면 아마 될 것 같습니다..
      • 이동기
        안녕하세요. 도움이 많이 되서 감사하게 잘 듣고 있습니다.
        질문이 있는데요,
        imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp)); 여기서 imagesx($im) - $sx - $marge_right 요 부분이 좌표가 정확이 어디인지 궁금합니다. 그리고 header('Content-type: image/png'); 이 위에 써도 되는건지 해서요~
        감사합니다.
      • kisstest
        14라인에서 카피할 파일의 너비, 높이를 가져올 때 imagesx($stamp), imagesy($stamp)를
        $sx, $sy 로 바꿔도 상관없지 않나요? imagesx($stamp), imagesy($stamp)를 쓰게 되면 'text.png'파일의
        너비, 높이를 두 번 계산하는거 같은데 ...
      • stockerman7
        imagecopy는 배경이미지를 타깃으로 소스 이미지의 위치와 보여질 크기를 지정하는 설정이군요...^^
        imagecopy(targetImg, sourceImg, sourceImgPosX, sourceImgPosY, sourceImgStartX, sourceImgStartY, sourceImgEndX, sourceImgEndY);
        마지막 네 개의 매개변수가 왜 필요한가 생각해보니... 삼각함수를 사용하는 거였군요...ㅋㅋ
      • Ni Ne Kim
        감사히 잘보고 있습니다.
        설명이 참 좋아서 이해 하는데 너무 많이 도움 됩니다.~
      • 샤핀
        감사합니다. ^^
      • 1588
        안녕하세요 감사합니다
      • 자타공인
        이미지에 보여지는 폰트를 바꾸려면 어떻게해야하나요?
        ++ UTF-8로 해도 한글이 깨지는데 해결방법이있나요?
      • 잉여잉여
        워터마크 예제에서 text.png 그림만을
        imagepng($stamp);
        imagedestroy($stamp);
        로 그려봤더니 회색 박스만 출력이 되는데 왜 그런걸까요?~
      • chase
        워터마크를 실행하면 글자는 안나오고 그림만 나오는데 어떻게 된걸까요...혹시나 해서, 텍스트가 있는 png만을 따로 출력 해보았는데 그냥 회색 사각형으로 나오네요......하지만 에디터에서는 투명배경에 글자 정상으로 나오고. 왜이럴까요? 다른 그림들은 잘 나옵니다. 웹브라우저랑 관련있는 걸까요? (flash player 등등 같은..)
      • 0132h
        실행 되었습니다.!~~^^
        감사합니다.
      • egoing
        저랑 똑같이 하면 안되고요. 자신의 상황에 맞게 내용을 수정해서 하셔야 합니다. 아마 경로 같은 것이 다르지 않을까요?
        대화보기
        • 0132h
          항상 감사합니다.
          window의 bitnami이용자입니다.
          php.ini의 파일 셋팅을 위처럼
          extension=php_gd2.dll
          extension_dir = "D:\BitNami\wampstack-5.4.21-0\php\ext"
          바꾸었지만..
          phpinfo();파일의 화면에서는 활성화되지 않습니다..
          그래서 인지 GD가 실행 안 되네요...
        • dubi
          GD가 위 방법대로 해도 실행이 되지않습니다.
          어떻게 해야하나요?
        • 설림
          엇... 안중요한거였군요; 이거 안되면 후반도 다 안되는줄....; 감사합니다 ㅎㅎㅎ
          대화보기
          • egoing
            지금 상황에서는 이것 저것 해보면서 문제를 파악해야 하기 때문에 도움을 댓글로 드리기는 어려울 것 같습니다. 이런 경우 일단 건너 뛰는 것이 상책입니다! 이거 모른다고 후속 수업에 아무 지장 없습니다. :)
            대화보기
            • 설림
              php.ini에서 ;extension=php_gd2.dll의 ;도 제거했고 경로도 확인했는데 gd 활성화가 안됩니다. 윈7 사용하고, 전에도 해보다가 안되길래 내컴이 이상한갑다 하고 포기했는데, 하드를 갈고 윈도를 새로 깔고나서 혹시나해서 다시해봤더니 여전히 localhost에서 gd가 안뜹니다. 혹시나 해서 아래 버튼실습도 따라했는데 깨진이미지 표시만 뜨네요... 어떡해야 강의를 계속 들을 수 있을까요?
            • openkwang
              GD가 지드래곤이 아니였군요;

              디자이너 의존도를 낮출 수 있는 멋진 기능이네요.
              앞으로 자주 이용해 봐야겠네요.
            • egoing
              금산님 문의 하신 내용은 제로보드 쪽의 지식이 많이 필요한데 저는 제로보드에 대해서는 아는 바가 별로 없어서요. 제로보드 측에 문의 하시거나, 좀 더 상세한 질문이 필요합니다.
              대화보기
              • 금산
                강의 잘듣고 있습니다.
                그런데요....
                윈도우에서 apmsetup, xe 설치해서 사용하고 있는데
                스킨을 적용하다보면 그림을 못불러와서 액박이 생깁니다.

                강의도중에 디렉토리 표시 \\를 리눅스와 윈도우가 다르다고 했는데
                스킨을 불러와 윈도우에 맞게 쉬운방법으로 소스를 고치는 법을 알으켜주심 좋겠는데요.....
              • egoing
                좋은 질문입니다. header 함수는 화면에 출력되는 데이터 이전에 오면 됩니다.

                예를들면 아래와 같은 예제는 화면에 내용을 출력하는 부분이 header 보다 먼저 오기 때문에 문제가 됩니다.

                아래는 안됩니다.

                <?php
                echo "test";
                header('Content-type: image/png');
                ?>


                아래도 안 됩니다.

                test
                <?php
                header('Content-type: image/png');
                ?>


                하지만 아래와 같은 함수는 데이터를 출력하지 않기 때문에 header 보다 먼저와도 문제가 되지 않죠.
                $sx = imagesx($stamp);
                대화보기
                • 찍찍이얌
                  강의 너무너무 잘 듣고 있습니다.
                  감사합니다.

                  그런데요
                  header('Content-type: image/png');
                  이 정보가 <?php 바로 다음에 와야 된다고 하신거 아니셨어요?
                버전 관리
                egoing
                현재 버전
                선택 버전
                graphittie 자세히 보기