1 December 2021

Rotate and merge image using data from css transform. In this code example the input data comes from javascript where visually image is rotated using css transform property. CSS transform and Imagick rotation are calculated differently. Css rotates image relative to it's center, but image dimensions stay the same. Imagick will change image dimensions when rotating the image. The answer is to calculate both image centers and operate relative to that.

Source code viewer
  1. $image = new Imagick();
  2. // Make sure transperancy stays.
  3. $image->setBackgroundColor(new ImagickPixel('transparent'));
  4. // Load base image.
  5. $image->readImage($base_image_path);
  6.  
  7. // Iterate through the new layers. Images that will be resized, rotated and merged to the base image.
  8. foreach ($layers as $layer) {
  9. $layer_image = new Imagick();
  10. // Make sure transperancy stays.
  11. $layer_image->setBackgroundColor(new ImagickPixel('transparent'));
  12. $layer_image->readImageBlob(file_get_contents($layer['url']));
  13. $layer_image->resizeImage((int) $layer['data']['width'], (int) $layer['data']['height'], Imagick::FILTER_UNDEFINED, 1);
  14. // This rotation comes from CSS transform.
  15. $layer_image->rotateImage(new ImagickPixel('transparent'), $layer['data']['rotation']);
  16.  
  17. // Calculate from base image left side to center of the applied image.
  18. $x_image_center = (int) $layer['data']['left'] + ((int) $layer['data']['width'] / 2);
  19. // Calculate how far rotated image should be from the left side.
  20. $left = $x_image_center - ($layer_image->getImageWidth() / 2);
  21.  
  22. // Calculate from base image top side to center of the applied image.
  23. $y_image_center = (int) $layer['data']['top'] + ((int) $layer['data']['height'] / 2);
  24. // Calculate how far rotated image should be from the left side.
  25. $top = $y_image_center - ($layer_image->getImageHeight() / 2);
  26.  
  27. // Merge layer to the base image.
  28. $image->compositeImage(
  29. $layer_image,
  30. Imagick::COMPOSITE_DEFAULT,
  31. round($left),
  32. round($top),
  33. Imagick::CHANNEL_ALPHA
  34. );
  35.  
  36. $layer_image->destroy();
  37. }
  38.  
  39. $image->destroy();
Programming Language: PHP