The right way to do this is to rotate and then crop using the correct transformation options.
Another way is moving, rotating, then moving again (simpler math, but more code).
$ x and $ y are the coordinates of the red dot.
private function rotateImage($image, $x, $y, $angle) { $widthOrig = imagesx($image); $heightOrig = imagesy($image); $rotatedImage = $this->createLayer($widthOrig * 2, $heightOrig * 2); imagecopyresampled($rotatedImage, $image, $widthOrig - $x, $heightOrig - $y, 0, 0, $widthOrig, $heightOrig, $widthOrig, $heightOrig); $rotatedImage = imagerotate($rotatedImage, $angle, imageColorAllocateAlpha($rotatedImage, 0, 0, 0, 127)); $width = imagesx($rotatedImage); $height = imagesy($rotatedImage); $image = $this->createLayer(); imagecopyresampled($image, $rotatedImage, 0, 0, $width / 2 - $x, $height / 2 - $y, $widthOrig, $heightOrig, $widthOrig, $heightOrig); return $image; } private function createLayer($width = 1080, $height = 1080) { $image = imagecreatetruecolor($width, $height); $color = imagecolorallocatealpha($image, 0, 0, 0, 127); imagefill($image, 0, 0, $color); return $image; }