Im PHP ist ImageOpenPolygon () eine sehr praktische Funktion, mit der offene Polygonlinien gezeichnet werden können. Diese Funktion funktioniert gut beim Zeichnen in kleinen Maßstäben. Wenn sie jedoch eine große Anzahl von Punkten oder großen Zeichnungsaufgaben beinhaltet, erscheint der Leistungsengpass allmählich. In diesem Artikel werden einige Möglichkeiten untersucht, um die Leistung von ImageOpenpolygon () in großem Maßstab zu verbessern.
ImageOpenpolygon () akzeptiert eine Reihe von Punkten, normalerweise ein eindimensionales Array, wie [x1, y1, x2, y2, ..., xn, yn] . Beim Generieren dieser Punktdaten:
Versuchen Sie, alle Punkte vorzubereiten und dynamische Berechnungen zu vermeiden, wenn Sie ImageOpenpolygon () aufrufen.
Stellen Sie sicher, dass das Array kompakt ist und keine zusätzlichen Nullwerte oder doppelten Punkte enthält.
// Nicht empfohlen:Dynamisch erzeugte Punkte
$points = [];
for ($i = 0; $i < 1000; $i++) {
$points[] = rand(0, 500);
$points[] = rand(0, 500);
}
imageopenpolygon($image, $points, count($points) / 2, $color);
// empfehlen:Das im Voraus vorbereitete festgelegte Array
$points = generatePoints(); // generatePoints()Geben Sie ein optimiertes eindimensionales Array intern zurück
imageopenpolygon($image, $points, count($points) / 2, $color);
Wenn Ihre Zeichnung viele doppelte oder ähnliche Polygone enthält, sollten Sie sich in Betracht ziehen:
Zwischen dem generierten DOT -Array in eine Datei oder einen Speicher (z. B. die Verwendung von Redis).
Verwenden Sie diese Daten jedes Mal wieder, wenn Sie zeichnen, anstatt sich jedes Mal zu regenerieren.
$cacheKey = 'polygon_points_large';
$points = apcu_fetch($cacheKey);
if ($points === false) {
$points = generateLargePolygonPoints();
apcu_store($cacheKey, $points);
}
imageopenpolygon($image, $points, count($points) / 2, $color);
HINWEIS: Verwenden von APCU -Cache erfordert, dass der Server APCU -Erweiterungen aktiviert.
Beim Zeichnen in großem Maßstab muss nicht unbedingt jedes Detail genau angezeigt werden. Eine angemessene Vereinfachung der Punkte kann die Leistung erheblich verbessern:
Verwenden Sie den Dezimierungsalgorithmus, um die Anzahl der Punkte zu verringern.
Die Stichprobenrate wird basierend auf der Zoomebene dynamisch bestimmt.
Einfacher Punktvereinbarungsbeispiel:
function simplifyPoints(array $points, int $threshold = 5): array {
$simplified = [];
for ($i = 0; $i < count($points) - 2; $i += 2) {
if ($i % ($threshold * 2) == 0) {
$simplified[] = $points[$i];
$simplified[] = $points[$i + 1];
}
}
return $simplified;
}
$originalPoints = generateVeryLargePolygon();
$points = simplifyPoints($originalPoints, 10);
imageopenpolygon($image, $points, count($points) / 2, $color);
Obwohl die GD -Bibliothek in PHP eingebaut ist und einfach zu bedienen ist, kann die Leistung von GD unter extremen Zeichnungsanforderungen nicht ausreichend sein. Halten:
Mit Imagick (PHP-Erweiterung basierend auf ImageMagick) wird bei der groß angelegten Grafikverarbeitung besser ausgeführt.
Rufen Sie in Kombination mit der CLI -Methode ein spezielles Zeichnungsprogramm auf (z. B. den Befehl ImageMagick über Shell_exec ()).
Beispiele verwenden Imagick:
$draw = new ImagickDraw();
$draw->setStrokeColor('black');
$draw->setFillColor('none');
$draw->setStrokeWidth(1);
$draw->polyline([
['x' => 10, 'y' => 10],
['x' => 100, 'y' => 30],
['x' => 50, 'y' => 100],
]);
$image = new Imagick();
$image->newImage(200, 200, "white");
$image->drawImage($draw);
$image->setImageFormat("png");
$image->writeImage('/var/www/html/uploads/output.png');
Wenn der Zeichnungsinhalt sehr groß ist, können Sie in Betracht ziehen, die Leinwand in mehrere kleine Stücke (Fliesen) zu teilen und sie dann nach dem Zeichnen zu synthetisieren:
Es werden jeweils nur sichtbare Bereiche gezeichnet.
Reduzieren Sie ein einmaliges Speicheraufwand.
function renderTile($startX, $startY, $width, $height, $points) {
$image = imagecreatetruecolor($width, $height);
$background = imagecolorallocate($image, 255, 255, 255);
imagefill($image, 0, 0, $background);
$color = imagecolorallocate($image, 0, 0, 0);
$tilePoints = filterPointsForTile($points, $startX, $startY, $width, $height);
if (!empty($tilePoints)) {
imageopenpolygon($image, $tilePoints, count($tilePoints) / 2, $color);
}
return $image;
}
Durch diese Methode kann die Belastung für jede Zeichnungsaktion stark reduziert und die Gesamtleistung verbessert werden.