[php] [GD] thumbnails krijgen een zwarte rand

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo allemaal,

Ik heb een gek probleem. Met onderstaande functie verklein ik jpg'jes. Dit werkt op server 1 prima. Op server 2 daarentegen krijgt de thumbnail die door deze functie wordt gecreeerd aan de rechter zijde en de onderkant een zwarte rand van 1 pixel.

Ik heb al ipv. imagecreatetruecolor gebruik gemaakt van ImageCreate maar dan zijn thumbnail inclusief ongewenste rand van belabberde kwaliteit.

server 1 (werkt goed)
php versie = 4.3.8
GD versie = 2.0.23 compatible

server 2 (ongewenste rand)
php versie = 4.3.3
GD versie = 2.0.15 compatible

Ik hoop niet dat het 'm zit in het versie verschil tussen De GD libraries ! Het is voor mij hoogst waarschijnlijk niet mogelijk om de php versie te updaten.

code:
1
2
3
4
5
6
7
8
9
10
11
function save($save="") {
    //save thumb
    if (empty($save)) $save=strtolower("./thumb.".$this->img["format"]);
    /* change ImageCreateTrueColor to ImageCreate if your GD not supported ImageCreateTrueColor function*/
    $this->img["des"] = imagecreatetruecolor($this->img["lebar_thumb"],$this->img["tinggi_thumb"]);
    //$this->img["des"] = ImageCreate($this->img["lebar_thumb"],$this->img["tinggi_thumb"]);
    @imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["lebar_thumb"], 
    $this->img["tinggi_thumb"], $this->img["lebar"], $this->img["tinggi"]);
    //JPEG
    imageJPEG($this->img["des"],"$save",$this->img["quality"]);
}


Kan iemand mij misschien helpen ? Heeft iemand dit probleem ook (gehad). Ik heb geen idee hoe dit komt. Ik zal aan deze werkwijze moeten vasthouden ivm. een naderende deadline.

vriendelijke groet en alvast bedankt,

Beimkirche

[ Voor 10% gewijzigd door Verwijderd op 01-09-2004 10:45 ]


Acties:
  • 0 Henk 'm!

  • jan-marten
  • Registratie: September 2000
  • Laatst online: 20-09 15:31
PHP:
1
2
3
4
5
imagecopyresized($im,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

//versus

@imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["lebar_thumb"], $this->img["tinggi_thumb"], $this->img["lebar"], $this->img["tinggi"]);

Haal die @ eens weg en zet de content type op text/plain of je ook foutmeldingen krijgt?

Ik heb deze problemen nog niet gezien (migratie van php 4.3.2 naar php 4.3.8).

Wat ik trouwens ook doe is kijken welke php/gd versie ik heb. Heel ranzig misschien maar het helpt wel:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function imagecreate_ws ($width,$height)
{
    // gd_info zit in php 4.3.0 en hoger. Lager dan 4.3.0 heeft geen truecolor...
    if (function_exists('gd_info'))
    {
        $resource = imagecreatetruecolor($width,$height);
    }
    else
    {
        $resource = imagecreate($width,$height);
    }

    return $resource;
}

Maar dat terzijde. Op een vergelijkbare manier zou je kunnen checken of de variabelen +1 moeten aan elke kant?...

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
bedankt voor je antwoord

Ik heb het @ weggehaald maar krijg geen foutmeldingen.

De regels:

code:
1
2
3
4
5
imagecopyresized($im,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

//versus

@imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["lebar_thumb"], $this->img["tinggi_thumb"], $this->img["lebar"], $this->img["tinggi"]);


lijken me precies hetzelfde, die van mij bevindt zich in een class.

Als ik de variabelen uit deze regel print krijg ik dit te zien:

oldpath : Resource id #14
newpath : Resource id #13
newwidth : 100
newheight : 100
oldwidth : 300
oldheight : 300

de thumbnail wordt op de goede plek opgeslagen. De thumbnail is inclusief zwarte rand 100 px.

Dus tja, ik ben nog niet veel verder vrees ik !

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

De zwarte rand aan de onderkant en de zijkant worden door afrondfouten veroorzaakt. Het bilineair interpolatie algoritme probeert dan punten te sampelen die buiten het bron plaatje liggen. Deze punten leveren zwart op en dit wordt door de rand pixels gemixed.

Nu weet ik niet wat voor berekening je gebruikt voor de thumbnail (lebar en tinggi vindt ik persoonlijk niet echt duidelijke var namen) maar het zou kunnen zijn dat dit floats zijn.

Is dit niet het geval (en dat lijkt me niet gezien de gegevens die je hierboven post), dan is het gewoon een bug in GD. Je zou het op kunnen lossen door de target size van de copy 1 pixel groter te maken, maar dat is eigenlijk alleen een smerige workaround om die bug.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
heel typisch, Janoz ik denk dat je verhaal over de afrond fouten best zou kunnen kloppen.

Ik heb voor de website waaraan ik nu werk viekante images nodig van 236X236 px (widthXheight). Als de webmaster deze upload met grootte 236X236 px dan gaat het thumbnail script er over en worden thumbnails gemaakt van 100X100 px. Wellicht is het feit dat het hier om vierkanten gaat hetgeen waardoor het mis gaat. De gehele site vormgeving is hier echter op gebaseerd.

bij uploaden:
236X236 ==> 1 px zwarte rand onder, 1 px zwarte rand rechts
236x235 ==> 1 px zwarte rand rechts
236x234 ==> 1 px zwarte rand rechts

de gehele class code:

code:
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class thumbnail
{
    var $img;

    function thumbnail($imgfile)
    {
        //detect image format
        $this->img["format"]=ereg_replace(".*\.(.*)$","\\1",$imgfile);
        $this->img["format"]=strtoupper($this->img["format"]);
        if ($this->img["format"]=="JPG" || $this->img["format"]=="JPEG") {
            //JPEG
            $this->img["format"]="JPEG";
            $this->img["src"] = ImageCreateFromJPEG ($imgfile);
        } elseif ($this->img["format"]=="PNG") {
            //PNG
            $this->img["format"]="PNG";
            $this->img["src"] = ImageCreateFromPNG ($imgfile);
        } elseif ($this->img["format"]=="GIF") {
            //GIF
            $this->img["format"]="GIF";
            $this->img["src"] = ImageCreateFromGIF ($imgfile);
        } elseif ($this->img["format"]=="WBMP") {
            //WBMP
            $this->img["format"]="WBMP";
            $this->img["src"] = ImageCreateFromWBMP ($imgfile);
        } else {
            //DEFAULT
            echo "Not Supported File";
            exit();
        }
        @$this->img["lebar"] = imagesx($this->img["src"]);
        @$this->img["tinggi"] = imagesy($this->img["src"]);
        //default quality jpeg
        $this->img["quality"]=75;
    }

    function size_height($size=100)
    {
        //height
        $this->img["tinggi_thumb"]=$size;
        @$this->img["lebar_thumb"] = ($this->img["tinggi_thumb"]/$this->img["tinggi"])*$this->img["lebar"];
    }

    function size_width($size=100)
    {
        //width
        $this->img["lebar_thumb"]=$size;
        @$this->img["tinggi_thumb"] = ($this->img["lebar_thumb"]/$this->img["lebar"])*$this->img["tinggi"];
    }

    function size_auto($size=100)
    {
        //size
        if ($this->img["lebar"]>=$this->img["tinggi"]) {
            $this->img["lebar_thumb"]=$size;
            @$this->img["tinggi_thumb"] = ($this->img["lebar_thumb"]/$this->img["lebar"])*$this->img["tinggi"];
        } else {
            $this->img["tinggi_thumb"]=$size;
            @$this->img["lebar_thumb"] = ($this->img["tinggi_thumb"]/$this->img["tinggi"])*$this->img["lebar"];
        }
    }

    function jpeg_quality($quality=75)
    {
        //jpeg quality
        $this->img["quality"]=$quality;
    }

    function save($save="")
    {
        //save thumb
        if (empty($save)) $save=strtolower("./thumb.".$this->img["format"]);
        /* change ImageCreateTrueColor to ImageCreate if your GD not supported ImageCreateTrueColor function*/
        $this->img["des"] = imagecreatetruecolor($this->img["lebar_thumb"],$this->img["tinggi_thumb"]);
            @imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["lebar_thumb"], $this->img["tinggi_thumb"], $this->img["lebar"], $this->img["tinggi"]);
        if ($this->img["format"]=="JPG" || $this->img["format"]=="JPEG") {
            //JPEG
            imageJPEG($this->img["des"],"$save",$this->img["quality"]);
        } elseif ($this->img["format"]=="PNG") {
            //PNG
            imagePNG($this->img["des"],"$save");
        } elseif ($this->img["format"]=="GIF") {
            //GIF
            imageGIF($this->img["des"],"$save");
        } elseif ($this->img["format"]=="WBMP") {
            //WBMP
            imageWBMP($this->img["des"],"$save");
        }
    }
}


zo gebruik ik het:

code:
1
2
3
4
5
6
$thumb=new thumbnail("./bestand.jpg");      // generate image_file, set filename to resize
//$thumb->size_width(100);                  // set width for thumbnail, or
//$thumb->size_height(300);                 // set height for thumbnail, or
$thumb->size_auto(100);                     // set the biggest width or height for thumbnail
$thumb->jpeg_quality(75);                   // [OPTIONAL] set quality for jpeg only (0 - 100) (worst - best), default = 75
$thumb->save("./bestand_thumbnail.jpg");                    // save your thumbnail to file


Al met al weet ik nu nog steeds niet goed hoe ik dit project moet gaan afronden ! :?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Het heeft niks met de vierkantheid te maken, maar gewoon met de afrond factor 236 -> 100. Upload een plaatje van 235 bij 235 en het is weg.

Om het probleem te omzeilen kun je de hack toepassen die ik voorstelde.
PHP:
1
imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["lebar_thumb"], $this->img["tinggi_thumb"], $this->img["lebar"]-1, $this->img["tinggi"]-1)

Hierdoor kan er niet buiten het plaatje gesampled worden door afrond fouten. Het probleem is en blijft een bug in php zelf dus veel anders dan een workaround kun je niet toepassen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Op het moment dat je gaat delen & vermenigvuldigen:

bijv:
$this->img["lebar_thumb"]/$this->img["lebar"])*$this->img["tinggi"]

even afronden met round/ceil/floor op hele pixels.

zoiets als:

this->round(img["lebar_thumb"]/$this->img["lebar"])*$this->img["tinggi"]);

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

^^ Als het werkelijk daar aan zou liggen, dan je slechts problemen gehad met 1 richting en niet allebij. Bij die if wordt de berekening namelijk alleen maar op de breedte (of hoogte, lebab en dinggi maken het voor mij niet zo duidelijk ;) ). Dit probleem is duidelijk een afrondings probleem binnen de code van php zelf.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Janoz schreef op 01 september 2004 @ 14:30:
Om het probleem te omzeilen kun je de hack toepassen die ik voorstelde. Hierdoor kan er niet buiten het plaatje gesampled worden door afrond fouten. Het probleem is en blijft een bug in php zelf dus veel anders dan een workaround kun je niet toepassen.
Deze work-around lijkt te werken ! Mag ik u hartelijk danken voor de hulp bij dit probleem. de tweaker gathering rules ! Nu kan ik weer verder....

[ Voor 31% gewijzigd door Verwijderd op 01-09-2004 16:09 ]

Pagina: 1