[PHP/GD] probleem met imagepolygon() en imagesetthickness()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Beste tweakers,

Ik ben vandaag al een tijd bezig met een rottig probleem: ik wil een polygon tekenen met GD met een dikke lijn.

Volgens mij moet dit kunnen m.b.v. imagesetthickness(), maar ik krijg dan af en toe rare output.
Voorbeeld:
Afbeeldingslocatie: http://www.gabber.nl/cp/geometry_1px.gif zonder imagesetthickness()
en
Afbeeldingslocatie: http://www.gabber.nl/cp/geometry_5px.gif met imagesetthickness($img, 5).

Het lijkt er op of de onderste 3 lijnstukken met een andere thickness worden getekend oid.
Als ik andere polygonen teken worden ze soms wel, soms niet goed getekend. Ook het lijnstuk waar het op fout gaat kan ik geen regelmaat in vinden.

Is dit een bekend probleem? Zo ja waardoor wordt het veroorzaakt?
(en zo nee, suggesties? :) )

Acties:
  • 0 Henk 'm!

Verwijderd

imagepolygon() is volgensmij zelf sluitend wat betekent dat de onderste 3 stukken dus waarschijnlijk de eerste polygon, de laaste polygon en de sluitende polygon zijn welke dus blijkbaar onbeinvloed zijn door imagesetthickness().

probeer de start coordinaat nogmaals als laaste coordinaate erbij te zetten zodat de sluitende polygon een lengte van 0 heeft. je zou ook nog over de 2 andere plolygonnen heen kunnen tekenen.

Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Probeer het eens in een truecolor mg resource?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
frickY: het is al een truecolor image.

Docey: ik begrijp niet echt wat je bedoelt... Ik gebruik imagepolygon() maar 1x om de vorm te tekenen?

De code die ik gebruik is:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function getPolygon($width, $border_width, $sides, $rotation = 0)
{
    $xcen = $width;
    $ycen = $width;
    $incr = 360/$sides;
    $angle = 180;
    $k = 0;
    $max_height = 0;
    for($j = 0; $j < $sides; $j++)
    {
        $points[$k] = $xcen + $width * sin(deg2rad($angle)) + $border_width;
        $k++;
        $points[$k] = $ycen + $width * cos(deg2rad($angle)) + $border_width;
        $max_height = max($max_height, $points[$k]);
        $k++;
        $angle += $incr;
    }
    
    $img = imagecreatetruecolor(2*$width+10, $max_height+$border_width+10);
    $bg = imagecolorallocate($img,255,255,255);
    ImageFill($img, 0, 0, $bg);
    imagecolorallocate($img, 255, 255, 255);
    $black = imagecolorallocate($img,0,0,0);

    imagesetthickness($img,$border_width);
    imagepolygon($img,$points,$sides,$black);

    if($rotation > 0)
        $img = imageRotate($img, $rotation, $bg);
    makeTransparent($img);

    header("Content-type: image/gif");
    imagegif ($img);
    imagedestroy($img);
}

Acties:
  • 0 Henk 'm!

Verwijderd

ik bedoel dat je met imagepolygon() een serie van xy coordinaten geeft waartussen de lijnen worden getekend. dus stel dat we een plaatje hebben van 100 bij 100 pixels. als ik dan een driehoek wil tekenen doe ik dat dus bijvoorbeeld zo:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// voorbereiden van het plaatje zou hier normaal staan maar dat skip ik dus even.

$points = array() // in deze array bewaren we onze coordinaten.

// eerste coordinaat
$points[0] = 50; // eerste coordinaat op de x-as oftewel breedt. dit is dus precies op het midden.
$points[1] = 20; // eerste coordinaat op de y-as oftewel hoogte. dit is dus op 20 pixels van de bovenkant.

$points[2] = 25; // ons plaatje is 100 pixels breedt. dus dit is op het 1e kwart van links.
$points[3] = 80; // en op 80% oftwel 80 pixels vanaf de bovenkant van het plaatje.

$points[4] = 75; // op het 3e kwart
$points[5] = 80; // zelfde hoogte.

//teken het polygon op plaatje $image met kleur $black.[s][/s]
imagepolygon($image, $points, count($points), $black);


dit tekent een driehoek door eerst naar de eerste coordinaat te gaan. op 50x en 20y. om vandaaruit een lijn te trekken naar 25x bij 80y om vandaaruit een lijn te trekken naar 75x bij 80y. omdat imagepolygon() zelf sluitend is wordt automatisch de lijn weer terug getrokken naar ons begin punt op 50x en 20y. ik vermoed dat deze lijn niet beinvloed wordt door de imagesetthickness() waarde en dus gewoon op 1pixel breedt wordt getekent.

omdat te voorkomen moet je dus nog een 4e coordinaat invullen, namelijk die naar 50x en 20y. dus de code wordt dan het volgende.


PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// voorbereiden van het plaatje zou hier normaal staan maar dat skip ik dus even.

$points = array() // in deze array bewaren we onze coordinaten.

// eerste coordinaat
$points[0] = 50; // eerste coordinaat op de x-as oftewel breedt. dit is dus precies op het midden.
$points[1] = 20; // eerste coordinaat op de y-as oftewel hoogte. dit is dus op 20 pixels van de bovenkant.

$points[2] = 25; // ons plaatje is 100 pixels breedt. dus dit is op het 1e kwart van links.
$points[3] = 80; // en op 80% oftwel 80 pixels vanaf de bovenkant van het plaatje.

$points[4] = 75; // op het 3e kwart
$points[5] = 80; // zelfde hoogte.

$points[6] = 50; // terug naar waar we begonnen op de x-as.
$points[7] = 20; // terug naar waar we begonnen op de y-as.

//teken het polygon op plaatje $image met kleur $black.
imagepolygon($image, $points, count($points), $black);


de sluitende polygon die de laaste en de eerste punt verbindt ligt nu tussen precies 2 dezelfde coordinaten, namelijk 20x bij 50y. hierdoor krijg je dat alle polygonen met de juiste dikte worden getekend. de sluitende polygoon wordt nu namelijk geteken met een lengte van 0 oftewel niet.

ik weet niet of dit je probleem oplost maar ik heb zo'n vermoeden dat dat het zou kunnen zijn.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ah ik snap het. Nog een keer toevoegen van eerste coordinaat heeft helaas geen invloed.
Het gekke is dat als ik een polygon met 8 kanten teken alles goed gaat.

Acties:
  • 0 Henk 'm!

Verwijderd

dan ligt het waarschijnlijk niet aan het tekenen van de polygonen zelf.

wat je mischien kunt proberen is het plaatje eerste vergroten, zeg 4x en daar de polygonen op tekenen en dan het plaatje weer verkleinen. mischien dat de polygonen te dicht op mekaar staan waardoor een dikte van 5 voor problemen zorgt. dit gaat je wel mem kosten dus probeer dit eerst als een soort van test-case.

wat je ook kan proberen is de lijnen zelf tekenen. je kan een functie schrijven die dit doet. die loopt gewoon door de coordinaten heen onthoudt de positie van de laaste coordinaat en pakt de volgende coordinate die je dan met imageline(); tekent. dit is mischien wat langzamer maar kost je niet een bak geheugen want grote GD plaatjes willen best veel ruimte innemen op je server als je veel hits hebt.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb hier nog een tijd mee zitten rommelen en uiteindelijk maar een bug report ingestuurd, net antwoord gekregen dat in het laatste CVS snapshot gefixt is.
Pagina: 1