manager = new ImageManager(new Driver()); } /** * Crop answer area from exam paper image * * @param string $imagePath Full path to the image * @param array $coordinates ['x' => int, 'y' => int, 'width' => int, 'height' => int] * @return string Path to the cropped image */ public function cropAnswerArea(string $imagePath, array $coordinates): string { $image = $this->manager->read($imagePath); // Get original dimensions $originalWidth = $image->width(); $originalHeight = $image->height(); // Default answer area: top-left corner (10% width, 15% height) $x = $coordinates['x'] ?? 0; $y = $coordinates['y'] ?? 0; $width = $coordinates['width'] ?? (int)($originalWidth * 0.1); $height = $coordinates['height'] ?? (int)($originalHeight * 0.15); // Crop the image $cropped = $image->crop($width, $height, $x, $y); // Save to temp directory $tempPath = storage_path('app/temp/answer_crops'); if (!file_exists($tempPath)) { mkdir($tempPath, 0755, true); } $filename = 'answer_' . basename($imagePath); $outputPath = $tempPath . '/' . $filename; $cropped->save($outputPath); \Log::info('Cropped answer area', [ 'original' => $imagePath, 'cropped' => $outputPath, 'dimensions' => "{$width}x{$height} at ({$x},{$y})" ]); return $outputPath; } /** * Crop answer area from a specific question's top-left corner * * @param string $imagePath Full path to the image * @param array $questionBbox Question's bounding box from Aliyun API * @return string Path to the cropped answer area */ public function cropQuestionAnswerArea(string $imagePath, array $questionBbox): string { $image = $this->manager->read($imagePath); // Question bbox is typically: [{'x': int, 'y': int}, ...] // We need the top-left corner of the question area $minX = PHP_INT_MAX; $minY = PHP_INT_MAX; $maxX = 0; $maxY = 0; foreach ($questionBbox as $point) { $minX = min($minX, $point['x']); $minY = min($minY, $point['y']); $maxX = max($maxX, $point['x']); $maxY = max($maxY, $point['y']); } // Answer area: top-left corner of the question // Typically 10-15% of question width and height $questionWidth = $maxX - $minX; $questionHeight = $maxY - $minY; $answerWidth = (int)($questionWidth * 0.15); $answerHeight = (int)($questionHeight * 0.20); // Crop from top-left of question $cropped = $image->crop($answerWidth, $answerHeight, $minX, $minY); // Save to temp directory $tempPath = storage_path('app/temp/answer_crops'); if (!file_exists($tempPath)) { mkdir($tempPath, 0755, true); } $filename = 'q_answer_' . uniqid() . '.jpg'; $outputPath = $tempPath . '/' . $filename; $cropped->save($outputPath); return $outputPath; } }