Add centered asset drawing support and refine image transformations

- Introduce `drawAssetCentered` method in `dynamicimages_image_t` for drawing assets visually centered on specified coordinates.
- Reset virtual canvas/page after image rotation in both `dynamicimages_asset_t` and `dynamicimages_image_t` to ensure consistent positioning.
- Update `machine_1` logic to use `drawAssetCentered` for improved thumb drawing and dynamic pivot alignment.
- Adjust thumb rotation calculations and positioning logic for better visual rendering.
This commit is contained in:
Jeppe Bundgaard
2026-01-27 14:56:58 +01:00
parent 493b4a2d6e
commit 2e7376f00a
4 changed files with 61 additions and 5 deletions
@@ -160,6 +160,41 @@ trait dynamicimages_image_t
return $this;
}
/**
* Draw an asset centered around the given coordinates.
* This is useful for rotated layers whose bounding box changes per angle,
* but should visually share the same pivot point.
*/
public function drawAssetCentered(dynamicimages_asset $asset, int $centerX, int $centerY, float $opacity = 1.0): dynamicimages_image_i
{
$this->assertCanvasInitialized();
if ($opacity < 0.0 || $opacity > 1.0) {
throw new \InvalidArgumentException('Opacity must be between 0.0 and 1.0');
}
$memoryImage = method_exists($asset, 'getMemoryImage') ? $asset->getMemoryImage() : null;
if ($memoryImage instanceof \Imagick) {
$layer = $memoryImage; // already a clone from asset
} else {
if (!is_readable($asset->getPath())) {
throw new \RuntimeException('Asset is not readable: ' . $asset->getPath());
}
$layer = new \Imagick();
$layer->readImage($asset->getPath());
}
$layer->setImageAlphaChannel(\Imagick::ALPHACHANNEL_SET);
if ($opacity < 1.0) {
$layer->evaluateImage(\Imagick::EVALUATE_MULTIPLY, $opacity, \Imagick::CHANNEL_ALPHA);
}
$w = (int)$layer->getImageWidth();
$h = (int)$layer->getImageHeight();
$x = (int)floor($centerX - $w / 2);
$y = (int)floor($centerY - $h / 2);
$this->image->compositeImage($layer, \Imagick::COMPOSITE_DEFAULT, $x, $y);
$layer->clear();
$layer->destroy();
return $this;
}
// ===== Transformations on the temporary image object =====
public function resize(int $width, int $height): dynamicimages_image_i
{
@@ -192,6 +227,8 @@ trait dynamicimages_image_t
$this->assertCanvasInitialized();
$bg = new \ImagickPixel($background === 'transparent' ? 'transparent' : $background);
$this->image->rotateImage($bg, $degrees);
// Reset virtual page so top-left is (0,0) after rotation; rotation occurs around center
$this->image->setImagePage(0, 0, 0, 0);
// Update stored dimensions
$this->canvasWidth = (int)$this->image->getImageWidth();
$this->canvasHeight = (int)$this->image->getImageHeight();