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. 공예나
    버튼 예제 안되시는 분들 중에
    imagestring($im, 4, $px, 9, $string, $orange);
    에서 px가 정수가 아니면 흰색 조그만 정사각형 박스만 뜨더라구요

    imagestring($im, 4, (int)$px, 9, $string, $orange);
    이렇게 바꿔서 해결했습니다.
  2. 드림보이
    2022.01.19. 파일 - 이미지 다루기 수강완료
  3. ggyuker
    22.01.03 수강완료 어려움
  4. 내가머더라
    gd2라는 파일은 없고
    gd imaging은 있는데
    이걸 gd2취급해서 적용했는데 코드가 제대로 작동하질 않네요? 어떻게 해야 할까요?
  5. jeisyoon
    2021.07.29 Image Control - OK
  6. solid
    이미지 안나오시는 분들은

    $stamp = imagecreatefrompng('text.png');
    $im = imagecreatefrompng('original.png');
    php파일과 png파일을 같은 경로에 두시고
    ./text.png
    ./original.png
    로 바꿔주시면 나옵니다
  7. 미댈
    추측하기로 브라우저 주소창에 ?text=coding 입력안하신것 같은데요

    http://localhost......ing
    위와 같이 입력하셔야 합니다.

    오래된 글이지만 다음 공부하시는 분을 위해 댓글 달아 봅니다.
    대화보기
    • Louie_Kim
      감사합니다. 잘 배우고 있습니다.
    • choon
      감사합니다.
    • Young-Ki Kim
      첫번째 예제의 코드를 아래와 같이 수정해 주니 되네요.
      위 예제대로 했을 때 잘 안되었던 것은, 연산 우선 순위 문제이었던 것 같습니다.
      =============================================
      $px = (imagesx($im) - (7.5 * strlen($string))) / 2;
    • 호두
      고맙습니다
    • 열정을가진
      저도 같은현상인데요ㅜㅜ 뭐가 잘못된건지... 혹 해결하셨나요?
      대화보기
      • 코딩잘하고싶어요 ㅎ
        음... 여기에 있는 이미지 파일로하면 잘 되는데, 왜 제 이미지로는 안되는지 모르겠습니다. 혹시 몰라서 png로 확장자도 맞추고 사이즈랑 전부 조절했는데도 이미지가 나오지 않고 화면 정중앙에 하얀색 네모박스만 나오는 걸요 ㅠㅠ
      • 코딩잘하고싶어요 ㅎ
        echo나 var_dump와 같이 데이터를 출력하는 코드나 공백(Enter)만 없으면 상관 없는 걸로 알고 있습니다.^^
        대화보기
        • 송성태
          잘 들었습니다.
          이미지도 재미있네요.
          코드가 이미지를 제어하네요.
          이렇게 생각하면 포토샵은 정말 거대한 코드 덩어리군요. ^^;
        • 최동희
          코드로 이미지 처리하는 기능은 웹브라우저에서 SVG나 Canvas로도 가능하니 참고하세요.
          SVG tutorial https://www.w3schools.com......asp
          Canvas tutorial https://www.w3schools.com......asp
          대화보기
          • 다시시작
            완료
          • Seongho Kim
            놀랍네요. 물론 포토샵에 능한 사람은 이미지를 사전 처리하면 되지만...php 기능만으로 이런 합성이 가능하다니 신기합니다. 왜 html 파일 소스가 따로 없나 했더니...php 파일만 호출하면 바로 생성해 주네요.
          • kimjs9105
            잘 들었습니다~~~~~
          • sheis
            잘 봤어요^^
          • 익명
            하단에서 2번째 보시면 egoing 님 남기신 답변에

            "데이터를 출력하지 않기 때문에 header 보다 먼저와도 문제가 되지 않죠."

            라고 합니다.

            데이터 출력되는 부분이 없다면 header 함수는 아래에 있어도 되는 것 같습니다.
            대화보기
            • meek
              계속 알수없는 오류가 나와서 나중에 복습할떄 해봐야겠네요 ..
            • HGERRARD
              구글에 php를 검색해 봤는데, php document보다 생활코딩이 상위 랭크에 있네요 ㅎㅎ
            • 김세창
              강의 잘 보고 배웠습니다!! ㅎㅎ

              강의를 들다보니, 한가지 의문점이 생겨 질문드립니다!^^
              이미지제어 1/2 강의에서는 header('Content-type: image/png'); 위에 아무것도 올수 없다고 하셨는데,
              워터마크 강의에서는
              header('Content-type: image/png'); 위에 여러 인자와 함수가 있습니다.

              왜 다른 것일까요??... 궁금합니다..
            • park
              이미지 다루는 예제를 시도할때마다 이미지가 깨져서 못하겠네요
              일단 패스...
            • 덜렁이
              생활코딩이라는 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
                  저랑 똑같이 하면 안되고요. 자신의 상황에 맞게 내용을 수정해서 하셔야 합니다. 아마 경로 같은 것이 다르지 않을까요?
                  대화보기
                  버전 관리
                  egoing
                  현재 버전
                  선택 버전
                  graphittie 자세히 보기