PHP에서 imageOpenPolygon ()은 열린 다각형 라인을 그리는 데 사용할 수있는 매우 실용적인 기능입니다. 이 기능은 작은 규모로 그리면 잘 수행되지만 많은 포인트 또는 대규모 드로잉 작업이 포함되면 성능 병목 현상이 점차 나타납니다. 이 기사는 대규모 도면에서 ImageOpenPolygon ()의 성능을 향상시키는 몇 가지 방법을 탐색합니다.
ImageOpenPolygon ()은 [x1, y1, x2, y2, ..., xn, yn] 과 같은 1 차원 배열, 일반적으로 1 차원 배열을 허용합니다. 이 포인트 데이터를 생성 할 때 :
ImageOpenPolygon ()을 호출 할 때 모든 점을 사전 창조하고 동적 계산을 피하십시오.
배열이 컴팩트하고 여분의 널 값 또는 중복점이 없는지 확인하십시오.
// 권장되지 않습니다:동적으로 생성 된 포인트
$points = [];
for ($i = 0; $i < 1000; $i++) {
$points[] = rand(0, 500);
$points[] = rand(0, 500);
}
imageopenpolygon($image, $points, count($points) / 2, $color);
// 추천하다:미리 준비한 고정 배열
$points = generatePoints(); // generatePoints()내부적으로 최적화 된 1 차원 배열을 반환하십시오
imageopenpolygon($image, $points, count($points) / 2, $color);
도면에 중복 또는 유사한 다각형이 많으면 다음을 고려하십시오.
생성 된 점 배열을 파일 또는 메모리 (예 : Redis 사용)로 캐시합니다.
매번 재생하는 대신이 데이터를 그릴 때마다 재사용하십시오.
$cacheKey = 'polygon_points_large';
$points = apcu_fetch($cacheKey);
if ($points === false) {
$points = generateLargePolygonPoints();
apcu_store($cacheKey, $points);
}
imageopenpolygon($image, $points, count($points) / 2, $color);
참고 : APCU 캐시를 사용하려면 서버를 사용하여 APCU 확장을 활성화해야합니다.
대규모로 그리면 모든 세부 사항을 정확하게 표시 할 필요는 없습니다. 포인트 세트의 적절한 단순화는 성능을 크게 향상시킬 수 있습니다.
Decimation 알고리즘을 사용하여 포인트 수를 줄입니다.
샘플링 속도는 줌 레벨에 따라 동적으로 결정됩니다.
간단한 점 단순화 예 :
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);
GD 라이브러리는 PHP에 내장되어 있고 사용하기 쉽지만 극한의 드로잉 요구 사항에서 GD의 성능이 충분하지 않을 수 있습니다. 고려하다:
Imagick (Imagemagick 기반 PHP 확장)을 사용하여 대규모 그래픽 처리에서 더 잘 수행됩니다.
CLI 메소드와 함께 특수 드로잉 프로그램 (예 : Shell_Exec ()을 통해 imageMagick 명령을 호출하는 등)을 호출하십시오.
예제는 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');
도면 내용이 매우 크면 캔버스를 여러 개의 작은 조각 (타일)으로 나눈 다음 그리기 후 합성을 고려할 수 있습니다.
보이는 영역 만 한 번에 그려집니다.
일회성 메모리 오버 헤드를 줄입니다.
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;
}
이 방법을 통해 각 드로잉 동작에 대한 부담이 크게 줄어들 수 있으며 전반적인 성능을 향상시킬 수 있습니다.