GD라이브러리 타원그리기에 대한 Bresenham알고리즘 적용

wkpark의 이미지

http://kldp.org/node/72772

코드놀이터, 코드퍼즐의 일환으로 제 PC에 묵혀두었던 허접 놀이개를 꺼내보았습니다.
----
GD라이브러리 다들 잘 아실겁니다.

이 라이브러리를 이용해서 pie 챠트를 그리거나 할때 그 얻어지는 타원의 그림을 보면 미려하지 않고 뭉게지는 것을 볼 수 있습니다. 예를 들어 다음과 같은 식입니다.


타원의 선이 약간 삐뚤빼뚤하죠. 이것은 gd라이브러리가 타원에 대한 Bresenham 알고리즘이 적용되지 않아서 그렇습니다.

타원에 대한 Bresenham알고리즘을 적용하면 다음과 같이 매끄러운 타원을 얻으실 수 있습니다.

(3년여 전 이 패치를 만들어서 gd 관리자에게 메일을 보냈으나 퇴짜맞고 개인적으로 쓰고있습니다. ^^;;)

제 기억으로, 이 패치는 gd1.x에 대해 만들어졌었고, gd2에도 거의 수정없이 적용할 수 있었던 것으로 기억합니다. gd라이브러리의 gdImageFilledArc() 함수를 고치셔야 합니다.

알고리즘에 관심 있으신 분 도전해보시기 바라며, 이번 기회에 이 패치가 gd에 적용될 수 있기를 바랍니다 :)

P.S.:
* 지져분한 패치지만 바로 올려버리면 재미가 없을것 같아서 일단은 첨부하지 않습니다~
* 최신 gd2도 gdImageEllipse()에 Bresenham알고리즘이 적용되어 있지 않습니다만, http://gcov.php.net/PHP_5_2/lcov/php-src/ext/gd/libgd/gd.c.gcov.php 에는 Bresenham알고리즘이 적용되어 있네요 ㅡ.ㅡ;;
* gdImageArc()는 Pie를 그릴 수 있으나, gdImageEllipse()는 타원 전체만을 그려줍니다.

File attachments: 
첨부파일 크기
Image icon gd1.png1.11 KB
Image icon gd2.png1.19 KB

댓글

송효진의 이미지

gdImageFilledEllipse() 함수가 삼각형 폴리곤을 루프를 돌며 그리도록 하는것은 아직 안고쳐졌네요.
제가 폴리곤 1개로 그리도록 패치를 해서 php 에 보낸 적이 있는데, 적용이 안되었습니다.
php스쿨에 올렸을 때도 컴파일 안된다는 분들이 있었는데,
제가 c 문법을 잘 몰라서 그런가봐요.

하나의 폴리곤으로 그리는것이 그냥은 별로 중요하지 않을 수 있습니다만,
브러시를 반투명 지정하면, 현재의 함수로는 예쁜(?)무늬가 생겨버립니다.

<?php

$im = imagecreatetruecolor(401, 802);
imagesavealpha($im, true);
imagealphablending($im, false);
imagefilledrectangle($im, 0, 0, 400, 801, 0x7fffffff);
imagealphablending($im, true);
imagefilledarc($im, 200, 200, 400, 400, 30, 270, 0xff0000, 0);
imagefilledarc($im, 200, 601, 400, 400, 30, 270, 0x40ff0000, 0);
imagepng($im, 'test.png');

echo '';

?>

php스쿨 패치게시물
php스쿨에서 j 라는 닉으로 활동하시던 분의 자간조정 패치도 함께 적용되면 좋겠습니다.

기왕이면 php 번들쪽에 적용되면 좋겠어요.^^

emerge money

wkpark의 이미지

이런 버그가 있었군요.. gd2 라이브러리는 2004년 이후로 개발이 중단된 상태인 것 같고, php5.x 에는 아예 libgd라고 번들로 gd라이브러리가 들어가있군요. graphviz도 마찬가지로 gd라이브러리가 포함되어 있고요. 개발이 중단된 라이브러리의 문제점인 듯..
http://www.boutell.com/gd/http/

온갖 참된 삶은 만남이다 --Martin Buber

wkpark의 이미지

일단 버그리포팅 해 두었습니다. http://bugs.php.net/bug.php?id=38517

gd관련 라이브러리와 번들로 포함된 libgd를 비교하다 보니,
번들된 libgd에 반영된 패치가 역으로 gd에 반영된 경우가 있더군요 :)

몇가지 문제점을 추가로 수정한 패치입니다.
http://chem.skku.ac.kr/~wkpark/linux/patch/php5.x-gd-bresenham3.patch

이 패치를 써서 그려본 그림:

온갖 참된 삶은 만남이다 --Martin Buber

wkpark의 이미지

예전 패치를 적용해 봤는데 hunk fail이 나서 ㅡㅡ;; 오늘에야 해봤습니다.

잘 되는군요 :) (php5.x의 번들된 gd패치)

php5.x에 번들된 gd소스를 잘 살펴보니 gd_arc_f_buggy.c라는 파일이 있군요. bresenham 알고리즘을 적용한 것 같은데 줄수는 약600여줄.., test가 제대로 작동하지 않아서 방치되어 있는..

P.S:
패치는 indent가 정리되지 않아 매우 지져분하지만, 아래에 다 있습니다. (php5.x용 패치는 php5로 시작합니다)
http://chem.skku.ac.kr/~wkpark/linux/patch/

온갖 참된 삶은 만남이다 --Martin Buber

wkpark의 이미지

붉은색 타원의 테두리 문제점도 수정하였습니다.
테두리의 원인은 "색채우기 + 테두리 그리기"를 수행하게 되는데, 테두리 그리기를 해서 두번 겹쳐지게 되기 때문입니다.

기타, indent수정하고 버그 고친 패치도 올려두었습니다.

문제점이 더 없는지 확인해보고 정리해보겠습니다.

문제를 막상 냈으나 저만 문제를 푸는 꼴이 되었군요 ㅡㅡ;; 좀 더 쉬운 문제를 내야 할 듯..

온갖 참된 삶은 만남이다 --Martin Buber

김정균의 이미지

저도 patch 를 3개정도 보냈다가 거절당한 경험이 있어서, 아예 safemode_exec_dir 은 보내지도 않고 안녕 리눅스에만 반영이 되어 있죠.

전 제가 거절 당한 것이, 영어를 너무 구리게 써서 보낸줄 알았는데, 그게 아니었다 보군요. 원래 벽이 높았나 봅니다. :-(

송효진의 이미지

타원패치를 빼니 php스쿨 j 님의 자간패치만 남는군요.
5.1.4에 맞췄습니다.
wkpark 님 패치랑 php 벅질라에 올렸으면 좋겠는데,
과연...::twisted::

emerge money

wkpark의 이미지

php말고 gd 원저자에게 연락해보셨나요? =3=33

php용 패치는 REGISTER_LONG_CONSTANT() 함수로도 상수를 등록해주셔야 할것 같습니다.

온갖 참된 삶은 만남이다 --Martin Buber

송효진의 이미지

gd/gd.c 에 보시면 strcmp 로 값을 검사하게 되어 있습니다.
libgd/ 의 것을 이용하려면 define 된 값이 필요하겠지만,
php 에서 전달시는 문자열로 충분합니다.

사용법
<?php
imagefttext($im, 12, 0, 20, 20, 0x0000ff, 'Gulim.ttf', "자간조정\n행간조정\n테스트",
array('charspacing' => 2, 'linespacing' => 2))
?>

emerge money

송효진의 이미지

테스트 해보니 한글이 안나오네요.
소스 뜯어보니 gdft.c 에 any2eucjp 라는 함수가 사용되네요.
gdFTEX_CHARMAP 이 넘어 왔는지 확인하고, (php 에서는 값을 넘길 방법을 제공하지 않습니다.)
안넘어 왔으면 UTF-8 로 세팅이 되는데,
문제는 밑에서 거의 무조건적으로 any2eucjp 함수를 실행하는군요.
JISX0208 이 define 되어 있으면 글꼴에 sjis 맵이 있는지 검사를 하는데,
맵이 있기만 하면 선택권이 박탈당하네요.
그냥 UTF-8 로 고정해 보려 했는데,
뭐가 문제인지 UTF-8 로 나오지를 않네요.
많이 바뀌었네...
----------------
젠투의 cjk flag 이 문제였군요.
cjk 는 일본어라는 의미가 아닌데 일본어 전용 옵션처럼 적용되어 있네요...

emerge money

z3r0k의 이미지

저도 그것 때문에 삽질 좀 했습니다.

어쨋든 PHP만 cjk 빼고 재컴팔하니 문제없이 돌아가는군요.

avelose의 이미지

GD라이브러리를 어디에 쓰시고들 계신 건가요?

개인적으로는 기본 도형 함수들의 경우엔 그래프를 그리는 것 이외에는 쓸데가 없어서 쓰지를 않습니다.
그래프의 경우에도 요즘에 뜨는[?? 아니라고 보지만..] SVG를 이용하거나[사용자들이 싫어하더군요. Active-X접근이 차단된 네트워크라서... 서버에 저장해 두고 연결했었긴하지만 어설픈 지식으로 Active-X설치를 꺼리더군요.] Flash[요즘엔 이것만 있으면 기본적으로 다들 설치를 하니]를 많이 씁니다.

동적 그래프 생성 시에도 쓸만하고요.[설마 GD로 동적 그래프를 생성하시는 분이 계신 것은...]
기본적으로 그래프 특성을 벡터로 그리고 변형해서 출력해 주면 예쁘게 그려 줘서 잘 쓰고 있습니다.[단순 그래프의 경우엔 리소스 비율도 낮고요.] 그래프를 타 형태로 변경하기도 쉽고 해서... 그래프용 Flash파일을 하나 만들어서 이곳 저곳에 쓰죠.[일반적으로 동일 파일을 여러번 호출하기 때문에 서버 부하도 좀 줄어들고요.]

게다가 매번 사용자가 원하는 형태의 그래프를 일일히 코딩해 주기도 귀찮아서..[사실 플래쉬도 귀찮지만] GD사용자들을 볼 때마다 박수를 보내드릴 뿐입니다.[GD는 거의 썸네일 이미지 생성할 때만 사용해서.]

p.s.1 소스 공유해 주신 글에 이런 댓글은 이상하지만.. ㅠㅠ
그리고 !!! 중요한 것.. PHP사이트에 GD로 그래프 그려놨으면 건들기 싫어지더군요. GD공부하기가 싫어서.
GD를 이용해서 폰트 처리하시는 것들도 마찬가지..[이런 꽁수는 어디에서.. 왜 파폭에선 임베디드폰트를 지원하지 않는지.. 설마 마소의 농간??]

p.s.2 아!! 생각났습니다. 엑셀파일 만들 때 쓰는군요. 그래픽 파일로 작성되어서 html파일을 .XLS로 확장자만 바꾸면 좋긴한데...
저의 경우엔 테이블만 받아서 폼을 만드는 VBA를 배포해서 그나마도 쓰지 않습니다만. [다만 엑셀 버전이 XP이하에서 지원하지 않는 단점 때문에 원성이 자자하죠. GD배우면 좋긴 좋은데.. ㅠㅠ]

'현실은 수학으로 표현할 수 없다.'
'수학은 거짓의 학문이다.'
'난 수학이 정말 싫다.'

'현실은 수학으로 표현할 수 없다.'
'수학은 거짓의 학문이다.'
'난 수학이 정말 싫다.'

익명사용자의 이미지

복잡하게 생각하실 것 없습니다. 목적에 맞게 쓰면 됩니다. php에서 gd를 이용하면 그림을 매우 손쉽게 살짝 변형하거나 할 수 있습니다. CAPTCHA같은 이미지 만들 때 쓸 수도 있고,
또, gd를 php에서만 쓰신다고 생각하면 오해입니다. gd를 사용하는 수많은 프로젝트를 찾아보시길 아마 깜짝 놀라실겁니다. (유명한 graphviz를 비롯해서 gd를 사용해서 날씨 그림 그린다던가 지도를 그리는 프로젝트 등등등)

P.S.: 수학 없이는 컴퓨터 반에 반도 제대로 활용하지 못합니다 >:>

avelose의 이미지

다른 용도로 더 많이 쓰시는 군요.[올바른 용도인가.] 보통 PHP에 GD를 같이 쓰는 경우가 많아서 웹쪽으로만 국한되어 생각을 했습니다.

컴퓨터는 거짓된 수학이 진실이 되는 모순된 기계이니까요. ㅋㅋ
그나마도 실수[컴퓨터에 이게 있어서는 안되는 거였는데..]의 연산은 수학식만으로 처리하면 정상적인 처리가 불가능..

2차원 평면에서 중점을 기준으로 한바퀴를 돌리다가 죽어도 정상적인 한바퀴가 안나오길래 꽁수로 처리했던 기억이 나네요. 쩝.

'현실은 수학으로 표현할 수 없다.'
'수학은 거짓의 학문이다.'
'난 수학이 정말 싫다.'

'현실은 수학으로 표현할 수 없다.'
'수학은 거짓의 학문이다.'
'난 수학이 정말 싫다.'

정태영의 이미지

libgd 프로젝트가 boutell 이 아닌 libgd.org 로 옮겨서 새롭게 시작한다는군요. :)

혹시나 예전에 패치나 개선안을 보냈다가 받아들여지지 않았던 경험이 있으신 분은 이 기회에 다시 패치를 보내보는 건 어떨까 싶습니다.

http://www.libgd.org/

----
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

송효진의 이미지

오랫만에 libgd.org 를 방문하니 정말 막강해 졌더군요.
근데 아직도 이 패치들은 적용을 안해주네요-_-^
회원가입이 안되어 FreeNode #libgd 방에 가서 혼자 궁시렁 댔습니다.
다들 자는지 답변이 없더군요.

혼자 궁시렁 내용

http://chem.skku.ac.kr/~wkpark/linux/patch/php5.x-gd-bresenham4.patch
this is Bresenham ellipse drawing algorithm patch
patcher is 'wkpark' (http://chem.skku.ac.kr/~wkpark/)
and
http://chem.skku.ac.kr/~wkpark/linux/patch/php5.x-gd-charspacing.patch
this is character spacing patch (like linespace)
patcher is 'j' (http://www.phpschool.com/gnuboard4/bbs/board.php?bo_table=tipntech&wr_id=20819)
please commit this patches.
thank you.

bugs.libgd.org 를 보니

png 에 압축이 되고, (2.0.12 때 부터 되네요.)

bmp 글도 좀 보이고, (된건 아니네요)

anti aliasing 이 되네요. bezier 곡선까지 되는것 같은데 http://pierre.libgd.org/polygons/
이건 어떻게 하라는건지는 안나오네요.

document 를 보니 animated gif 를 만들 수 있네요. http://libgd.org/OldImageCreation

under the umbrella of php.net 보고 php.net 메뉴얼 다시 보니까
imagepng() 에 압축과 필터가 추가되었군요! png 필터는 잘 모르겠는데...
imageconvolution() 요건 또 웬 포토샵급인가요! 도대체 값을 주는 기준이 뭐죠?
imagefilter() 알아보기 쉬운 필터군요. 하지만 convolution 이 웬지 더 막강할것 같네요.

animated gif 는 binding 되지 않았네요.
포인터 처리하는듯 해서 제가 함수만들 만한 레벨이 아니네요.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇개 안되요~

정태영의 이미지

Quote:
under the umbrella of php.net 보고 php.net 메뉴얼 다시 보니까
imagepng() 에 압축과 필터가 추가되었군요! png 필터는 잘 모르겠는데...
imageconvolution() 요건 또 웬 포토샵급인가요! 도대체 값을 주는 기준이 뭐죠?
imagefilter() 알아보기 쉬운 필터군요. 하지만 convolution 이 웬지 더 막강할것 같네요.

libgd 에도 포함된줄 알았는데 그건 아니었네요. :)

php 에 번들된 libgd 에만 포함되어 있는 기능이었던 것 같은데, imageconvolution 의 경우 이미지가 커질경우 엄청나게 느리다는 단점이 있습니다. :) 특정 사이즈 이상이라면 FFT->multiply->iFFT 를 하는게 훨씬 빠르지만 그런 처리는 아직 안들어있거든요.

잘 알려진 이미지 필터링 마스크는 다음과 같은 것들이 있습니다.

blur
1 1 1
1 1 1
1 1 1

laplace (2차 미분을 통한 edge 검출용)
0 -1 0
-1 4 -1
0 -1 0

gradient (가로방향)
-1 0 1
-1 0 1
-1 0 1

gradient (세로방향)
-1 -1 -1
0 0 0
1 1 1

sharpen (original + edge)
0 -1 0
-1 5 -1
0 -1 0

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

송효진의 이미지

우와~
그걸 어떻게 계산하는지 찾아보려면 무슨 검색어가 필요할까요?

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇개 안되요~

정태영의 이미지

주파수 특성으로 봤을 때 edge 성분은 고주파 부분에 존재하므로 low pass signal 을 얻으면 blur, high pass signal 을 얻어내면 edge 가 되는 것이구요. sharpen 같은 것은 원래 영상에 edge 부분을 더해서 edge 부분을 강조하는 것을 통해 구현할 수 있습니다.

위에서 얘기한 것 같은 것들은 fourier transform 의 discrete 버젼인 DFT 를 통해 실제 확인을 해보실 수 있을겁니다. (fast algorithm 을 적용한 FFT를 주로 사용합니다. fftw3 를 사용하시면 직접 구현하지 않으셔도 됩니다. 실제 matlab 등에서도 fftw 를 사용하구요.)

그리고 주파수 영역에서가 아닌 그냥 이미지를 가지고 필터링을 하기 위해서는 convolution 을 이용합니다. 대게 계산 복잡도 때문에 convolution mask 를 크게 잡지 않고 3x3 정도로 많이 사용하게 됩니다. 제가 위에 써놓은 mask 들은 잘 알려진 mask 들 중의 하나이구요.

관련해서 검색을 해보고 싶으시다면 대강 아래 와 같은 검색어를 이용해보시기 바랍니다.
blur -> gaussian blur, median filter, mean filter
edge detect -> laplacian mask, gradient image processing

edge detect 관련해서는 프랫이던가 --; 하튼 저거 말고도 종류가 많은데 요새 제 마리가 점점 녹아가고 있어서 기억이 잘 나질 않네요.

관련해서 깊이있게 공부를 해보시고 싶으시다면 주위에 있는 서점에서 image processing 관련된 책들을 찾아보세요.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

송효진의 이미지

감사합니다.

emerge money
http://wiki.kldp.org/wiki.php/GentooInstallSimple - 명령어도 몇개 안되요~

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.