달력 만들기 (PHP)

codebank의 이미지

안녕하십니까.

이전에 IP를 이용하여 지역을 찾는 방법을 올렸을 때 이야기하던 달력 만드는 방법을 PHP로 구현해봤습니다.

그냥 gd를 배우면서 만들어본것이라 볼 것은 별로 없습니다.
환경은 이전과 똑같은 환경입니다.
Gentoo 배포판에 PHP 5.2.6, gd(TTF지원)가 있으면 됩니다.

사용방법은 아래 소스를 이용합니다.(저는 index.php라는 이름을 부여해서 이름을 넣지않고
/?img=1 과 같이 생략해서 넣었습니다.)
동작은 원하는 이미지를 배경에 넣고 이미지 하단에 반투명 부분을 만들어 그곳에 Logo같은 것을 찍고 한달을 기준으로 날자를 일렬로 찍습니다.

사용할 이미지는 jpeg형태를 읽도록 만들었으며

back01.jpg, back02.jpg, back03.jpg...

형태로 이름을 부여하여 img=1은 back01.jpg를 img=3은 back03.jpg를 기본 배경으로 선택할
수 있도록 했습니다.
이미지의 크기에 상관없이 1024x768 사이즈에 맞도록 수정됨으로 이미지 변형이
생길 수도 있을 겁니다.(사실은 태두리 때문에 몇 pixel씩 더 줄어듭니다.)
소스에도 있지만 사용방법은

http://localhost/wallpaper/index.php?img=2&year=2013&month=12

http://localhost/wallpaper/?img=2

http://localhost/wallpaper/?img=2&year=2013

http://localhost/wallpaper/?img=2&year=2013&month=12

이렇게하는 것이 정석이며 img는 생략할 수 없고 year이나 month가 생략되면
올해 이번달을 year, month대신에 넣도록 되어있습니다.

원래 type이 존재해서 표시되는 달력이 가로로 될 것인지 세로로 될것인지를 결정하도록
되어있었는데 안타갑게도 그 소스는 날아가 버려서 이전에 만들어 놓은 소스를 올리게
되었습니다.
세로로 출력되는 것도 아래 소스를 보면 어렵지 않으므로 한번 만들어보시는 것도
재미있을 겁니다.(다만 좌표 계산에 신경이 조금 쓰이겠지만요. :-))
(일반 달력 형태도 어려운 것은 아니니 한번 직접 작성해보시는 것도 재미있을 겁니다. :-))

<?php
// 시스템 locale을 설정해줍니다.
setlocale (LC_ALL, "ko_KR.eucKR");
// 출력 이미지는 1024x768로 지정했습니다.
$max_width = 1024;
$max_height = 768;
// 달력이 출력될 크기를 지정합니다.
$alpha_width = $max_width - 12;
$alpha_height = 120;
// 폰트는 Eunjin.ttf를 사용했습니다. 원하는 폰트를 사용하세요.
$fontname = "Eunjin.ttf";
// 일주일을 나타냅니다. weekly_e는 영문으로 나타날때 입니다.
$weekly = array ("일", "월", "화", "수", "목", "금", "토");
$weekly_e = array ("Su", "Mo", "Tu", "We", "Th", "Fr", "Sa");
// 기본 이미지를 지정하지 않으면 처음 이미지를 지정합니다.
if (!$img)
$image_name = "back01.jpg";
else {
if ($img < 10) $image_name = "back0" . $img . ".jpg";
else $image_name = "back" . $img . ".jpg";
}
// 년도와 달이 있다면 그것을 사용하고 없다면 올해 이번달을 기준으로 사용합니다.
$today_year = $year ? $year : date ('Y');
$today_month = $month ? $month : date ('n');
$today_week = date ('w', mktime (0, 0, 0, $today_month, 1, $today_year));
$today_last = date ('t', mktime (0, 0, 0, $today_month, 1, $today_year));
$today_string = date ('F', mktime (0, 0, 0, $today_month, 1, $today_year));

// 화면에 표시할 이미지를 만듦니다.
$base = @ImageCreateTrueColor ($max_width, $max_height)
or die ("Cannot Initialize new GD image stream");
// 기본색을 지정합니다.
$bg = ImageColorAllocate ($base, 200, 200, 200);
$black = ImageColorAllocate ($base, 0, 0, 0);
$white = ImageColorAllocate ($base, 255, 255, 255);
$red = ImageColorAllocate ($base, 255, 0, 0);
$green = ImageColorAllocate ($base, 0, 255, 0);
$blue = ImageColorAllocate ($base, 0, 0, 255);
// 배경을 채웁니다.
ImageFill ($base, 0, 0, $bg);
// 배경이미지를 읽어들입니다. (기본이미지는 jpeg로 지정했습니다.)
$back = @ImageCreateFromJpeg ($image_name)
or die ("Cannot Initialize read JPEG image stream");
// 화면에 맞도록 이미지 크기를 수정하여 화면에 표시할 이미지에 복사합니다.
ImageCopyResized ($base, $back, 3, 3, 0, 0, $max_width - 6, $max_height - 6, ImageSx ($back), ImageSy ($back));
// 배경이미지를 닫습니다.
ImageDestroy ($back);

// 화면 하단에 투명하게 날짜를 표시할 부분의 만듦니다.
$alpha = @ImageCreateTrueColor ($alpha_width, $alpha_height)
or die ("Cannot Initialize new GD image stream");
// 배경색을 지정합니다.(회색)
$bg = ImageColorAllocate ($alpha, 200, 200, 200);
ImageFill ($alpha, 0, 0, $bg);
// 투명하게 보이도록 지정
ImageAlphaBlending ($base, TRUE);
ImageAlphaBlending ($alpha, TRUE);
// 날짜 표시부분을 화면에 표시할 이미지에 붙입니다.
ImageCopyMerge ($base, $alpha, 6, $max_height - $alpha_height - 6, 0, 0, $alpha_width, $alpha_height, 50);
// 투명이미지를 닫습니다.
ImageDestroy ($alpha);

// 이부분은 회사 Logo를 붙여보려고 넣어놓았습니다.
$logo = @ImageCreateFromPng ("logo.png")
or die ("Cannot Initialize read PNG image stream");
ImageAlphaBlending ($logo, TRUE);
// 날짜 앞부분에 이미지를 넣습니다.
ImageCopy ($base, $logo, 15, $max_height - $alpha_height + 30, 0, 0, ImageSx ($logo), ImageSy ($logo));
ImageDestroy ($logo);

// 날자를 표시하는 부분입니다.
// 적당한 위치값을 선정해서 글자를 표시합니다.
$position_x = 170;
$position_y = $max_height - $alpha_height + 80;
if ($today_month < 10)
$month_plus = 30;
else
$month_plus = 0;
// 달을 표시합니다.
ImageTTFText ($base, 40, 0, $position_x + $month_plus, $position_y, $black, $fontname, $today_month);
// 달을 글자로 표시합니다.
ImageTTFText ($base, 16, 0, $position_x + 80, $position_y, $black, $fontname, $today_string);
// 년을 표시합니다.
ImageTTFText ($base, 16, 0, $position_x + 80, $position_y - 30, $green, $fontname, $today_year);

// 원래 encoding은 한글과 영문을 구분하려고 했지만 잘 동작하지 않아서 영문만을 표시합니다.
$encoding = 0;
// 날자를 순서대로 나열합니다.
// 일요일은 빨간색, 토요일은 파란색, 평일은 검은색으로 표시합니다.
// 조금만 응용하면 원하는 년도 달, 일에 대한 표시도 넣을 수 있습니다.
for ($i = 1; $i <= $today_last; $i++) {
// 표시색 결정
if ($today_week == 0)
$color = $red;
elseif ($today_week == 6)
$color = $blue;
else
$color = $black;
// 월화수목금토일을 표시합니다.
// 원래는 글꼴에 따라서 한글과 영문을 교대로 나오도록 만들려고 했지만 능력부족으로...
if ($encoding == 1) {
$han = iconv ("EUC-KR", "UTF-8", $weekly [$today_week]);
if ($han == FALSE) {
$han = $weekly_e [$today_week];
$encoding = 0;
}
ImageTTFText ($base, 10, 0, $position_x + 180 + $i * 20, $position_y - 30, $color, $fontname, $han);
} else
ImageTTFText ($base, 10, 0, $position_x + 180 + $i * 20, $position_y - 30, $color, $fontname, $weekly_e [$today_week]);
// 날자를 표시합니다.
$st = vsprintf ("%2d", $i);
ImageTTFText ($base, 10, 0, $position_x + 180 + $i * 20, $position_y, $color, $fontname, $st);
$today_week = ($today_week + 1) % 7;
}

// 이미지를 화면에 출력합니다.
header ("Content-type: image/png");
ImagePng ($base);
ImageDestroy ($base);
?>

좀더 커다란 달력 이미지를 원하신다면 그에 맞춰서 글자등의 출력을 맞춰주는 작업이 추가로 필요할
것으로 생각합니다.
화면으로 출력된 이미지는 마우스 오른쪽 버튼을 이용해서 다른 이름으로 저장하기를
하신다면 화면 배경이미지로도 이용하실 수 있습니다. :-)

감사합니다.

Forums: 
hiseob의 이미지

주소가 LOCALHOST 네요 ^^ 어쨌든 잘봤습니다

codebank의 이미지

아~ 주소가 localhost인 이유는 '이렇게 사용한다...'라는 예제를 보여주기 위해서입니다.
실제로 로컬에서 작업하고 실제 돌아가는 웹서버에 한번 올려서 테스트해보고
사용하지 않고 있는... :-)
바탕화면을 만들거나 할 때 사용하려고 했다가 잊고 있었는데 저번 GeoIP때 한번
언급하고 또 잊었다가 설명만 붙여서 올려놓은 겁니다.
잘만들어지지도 최적화 되지도 않았고 그냥 gd 라이브러리사용방법이나 FreeType사용
방법만 보셔도 괜찮을 것 같아서 올려놓았죠. :-)
------------------------------
좋은 하루 되세요.

------------------------------
좋은 하루 되세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.