Abgerundet transparent _smooth_ Ecken mit imagecopyresampled() PHP-GD
Ich brauche ein script, das macht die abgerundeten transparenten Ecken auf dem Bild geliefert. Ich hab eines gefunden und es funktioniert gut, außer der einen Sache: die angewandte Ecken nicht sehen glatt aus. Die imageantialias()
wirft Fatal Error da PHP läuft auf Debian und re-kompilieren ist es nicht eine option.
Den trick, den ich gefunden habe, um die Ecken glatt ausschaut, ist die Größe des Bildes mit imagecopyresampled()
wie die folgenden:
- image vorbereiten;
- imagecopyresample es 10x Größe;
- zeichnen Sie die Ecken mit einer besonderen Farbe;
- machen, dass die Farbe transparent;
- verkleinern Sie das Bild auf seine ursprüngliche Größe
Aber hier kommt das problem: die Ecken des Ergebnis-Bild (nach Schritt 5) sind glatt, aber nicht transparent. Beim senden an die Ausgabe das Bild nach Schritt 4 (also vor ab es ist in der Größe) – alles ist wie es sein sollte.
Hier ist der Teil, der code dafür verantwortlich, Ecken abgerundet:
//$dest = image-Ressource $q=10; //machen alles 10x größer $new_width=$width*$q; $new_height=$height*$q; $radius=$radius*$q; $vergrößert=imagecreatetruecolor($new_width, $new_height); imagecopyresampled($vergrößert, $dest, 0,0, 0,0, $new_width,$new_height, ($new_width/$q),($new_height/$f)); //aufnehmen der einzigartigen Farbe $gefunden = false; while($gefunden == false) { $r = rand(0, 255); $g = rand(0, 255); $b = rand(0, 255); wenn(imagecolorexact($vergrößert, $r, $g, $b) != (-1)) { $gefunden = true; } } $colorcode = imagecolorallocate($vergrößert, $r, $g, $b); //Zeichnung Ecken imagearc($vergrößert, $radius-1, $radius-1, $radius*2, $radius*2, 180, 270, $colorcode); imagefilltoborder($vergrößert,, 0, 0, $colorcode, $colorcode); imagearc($vergrößert, $new_width-$radius, $radius-1, $radius*2, $radius*2, 270, 0, $colorcode); imagefilltoborder($vergrößert, $new_width-1, 0, $colorcode, $colorcode); imagearc($vergrößert, $radius-1, $new_height-$radius, $radius*2, $radius*2, 90, 180, $colorcode); imagefilltoborder($vergrößert, 0, $new_height-1, $colorcode, $colorcode); imagearc($vergrößert, $new_width-$radius, $new_height-$radius, $radius*2, $radius*2, 0, 90, $colorcode); imagefilltoborder($vergrößert, $new_width-1, $new_height-1, $colorcode, $colorcode); //machen die einzigartige Farbe transparent imagecolortransparent($vergrößert, $colorcode); //verkleinert das vergrößerte Bild auf die ursprüngliche Größe //erwartet Ecken transparent bleiben imagecopyresampled($dest, $vergrößert, 0,0, 0,0, ($new_width/$q),($new_height/$q"), $new_width,$new_height); //aber Sie sind nicht //senden $vergrößerten Ausgabe für Testzwecke $dest=$vergrößert; //Ausgabe $dest als image/png
So wie Sie sehen können, das problem tritt auf, wenn vergrößerte Bild wird imagecopyresampled zu seiner ursprünglichen Größe. Die transparenten Ecken gefüllt mit den $colorcode
Farbe. Ich habe das Spiel mit imagesavealpha()
und imagealphablending()
als empfohlen, aber ohne Ergebnis.
Bitte helfen Sie mir, um diese Arbeit zu machen.
P. S. Diese können hilfreich sein: beim Upload der große PNG zu imgur.com er hatte es in JPG umgewandelt und wie Sie sehen können, alle Ecken bekam gefüllt mit, die sehr restauriert $colorcode.
P. S. Hoffe ich werde nicht gebannt für übernutzung das Wort "Erweiterung" 🙂
- Diese Linie führt zu tödlichen Fehler, wenn Sie große W/H (vergessen Sie nicht, dass immer mehr original-W/H mit 10)...
$magnified=imagecreatetruecolor($new_width, $new_height);
. Drücken Sie die Speicher-limits (oder Grenzen, die Sie gesetzt haben, in php.ini). - Ich habe ein vordefiniertes array von Bild-Typen, die ich brauchen kann, enthält Informationen über Breite, Höhe und Ecken. Ich habe immer
imageantialias()
schwerwiegender Fehler vor tricks mit der Bild-Größe, so dass ich sicher bin, dass das Debian-Problem.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Nach einigen Stunden des testens und Tritte meinen Kopf gegen die Wand, ich glaube ich habe die Lösung gefunden. Problem war, über die Zuteilung transparente Farbe mit
imagecolorallocate()
. Bekomme ich es nicht auf den ersten Blick. Es war der völlig falsche Ansatz. Allerdingsimagecolorallocatealpha()
hat mir geholfen, eine Menge.Auch, alpha blending muss ausgeschaltet sein, bevor Sie Sie speichern den alpha-Kanal auf Schicht arbeiten. Aber es muss getan werden direkt nach Erstellung leere true-color-Bild, wie
Dieser code ist ein Schlüssel für die erste glatte Ecken im transparenten Bereich nach Größe-down.
Nachdem alle, ich habe geschrieben diese Funktion
Getestet hab ich es mit ein paar Bilder und es kehrte Bild mit glatten Ecken für jede bg Farbe.
Ausgabe
Original Bild
IM BROWSER (Gleiche png-Datei 'test.png')
Er kehrt schließlich völlig transparent alpha-Kanal, so können Sie das Bild auf jedem hintergrund, die Sie wollen.
Hätte ich fast vergessen zu posten Funktionscode 🙂
Funktion imageCreateCorners($sourceImageFile, $radius)
Funktion gibt GD-Objekt oder false.
Funktion arbeitet mit festen JPEG -, GIF-und PNG-Bilder. Auch, es funktioniert Super mit transparenten PNGs und GIFs.
$magnified
zu$dest
- und exportieren der letzteren. Ich habe versuchtimagecolortransparent($dest, $colorcode);
aber der Punkt ist, dass ich entfernen müssen$colorcode
vor Skalierung das Bild unten um Ecken klar. 4). Ich verwendet, die für test Zwecke – nur für export$magnified
und zu sehen, wie es aussieht.header();
bei export der Bühne mit content-type und cache-control-Einstellungen. Für abgerundete Bilder, die ich senden Bild - /png-Header. Ich kann verwenden$q=5;
statt 10, um Speicher zu speichern, ist das in Ordnung, aber ich brauche dieses Skript funktioniert wie erwartet den ersten. 6). Sind die Ecken in deinem Beispiel transparent oder mit fester hintergrund? Ich sehe schwarz "Rauschen" auf den Mann an der hand haben, haben Sie entfernen$colorcode
nach der Skalierung nach unten?imagecolortransparent($dest, $colorcode);
entfernt$colorcode
aus dem bereits verkleinerten Bild, und hält das semi-transparente Teile. Ich brauche, um$colorcode
transparent, wenn das Bild ist immer noch groß und abgerundete Ränder sind scharf.versuchen, diese ...
Verbesserte code von @Wh1T3h4Ck5.
Diese Funktion nehmen das Bild, und stellen Sie Runde Ecken, ohne Verschwendung von Speicher. Auch muss es schneller arbeiten auf riesige Bilder.
Zum Beispiel 1024*1024-Bild brauchen 400MB temp-Bild in original-code. Jetzt nur 230 KB. (wenn Sie die Verwendung von radius 10 px).
Funktion nehmen Sie die GD-image-Objekt, radius in px und zurück GD-Bild-Objekt. Derzeit ist es "wie original" GD-Bild-Objekt.
Funktion übernehmen Größe des Bildes ist größer vom radius. Genau, es muss größer (oder gleich) von
($radius + 2)*2
auf jeder Seite.Auch die Funktion set
imagealphablending
zutrue
für dieses Bild. Wenn Sie brauchen, speichern in png nicht vergessen setimagesavealpha
zutrue
.