public function compare_to_string($content) {
return $this->get_contenthash() === file_storage::hash_from_string($content);
}
+
+ /**
+ * Generate a rotated image for this stored_file based on exif information.
+ *
+ * @return array|false False when a problem occurs, else the image data and image size.
+ * @since Moodle 3.8
+ */
+ public function rotate_image() {
+ $content = $this->get_content();
+ $mimetype = $this->get_mimetype();
+
+ if ($mimetype === "image/jpeg" && function_exists("exif_read_data")) {
+ $exif = @exif_read_data("data://image/jpeg;base64," . base64_encode($content));
+ if (isset($exif['ExifImageWidth']) && isset($exif['ExifImageLength']) && isset($exif['Orientation'])) {
+ $rotation = [
+ 3 => -180,
+ 6 => -90,
+ 8 => -270,
+ ];
+ $orientation = $exif['Orientation'];
+ if ($orientation !== 1) {
+ $source = @imagecreatefromstring($content);
+ $data = @imagerotate($source, $rotation[$orientation], 0);
+ if (!empty($data)) {
+ if ($orientation == 1 || $orientation == 3) {
+ $size = [
+ 'width' => $exif["ExifImageWidth"],
+ 'height' => $exif["ExifImageLength"],
+ ];
+ } else {
+ $size = [
+ 'height' => $exif["ExifImageWidth"],
+ 'width' => $exif["ExifImageLength"],
+ ];
+ }
+ imagedestroy($source);
+ return [$data, $size];
+ }
+ }
+ }
+ }
+ return [false, false];
+ }
}
const STAMPS_FILEAREA = 'stamps';
/** Filename for combined pdf */
const COMBINED_PDF_FILENAME = 'combined.pdf';
+ /** Temporary place to save JPG Image to PDF file */
+ const TMP_JPG_TO_PDF_FILEAREA = 'tmp_jpg_to_pdf';
+ /** Temporary place to save (Automatically) Rotated JPG FILE */
+ const TMP_ROTATED_JPG_FILEAREA = 'tmp_rotated_jpg';
/** Hash of blank pdf */
const BLANK_PDF_HASH = '4c803c92c71f21b423d13de570c8a09e0a31c718';
$pluginfiles = $plugin->get_files($submission, $user);
foreach ($pluginfiles as $filename => $file) {
if ($file instanceof \stored_file) {
- if ($file->get_mimetype() === 'application/pdf') {
+ $mimetype = $file->get_mimetype();
+ // PDF File, no conversion required.
+ if ($mimetype === 'application/pdf') {
$files[$filename] = $file;
- } else if ($convertedfile = $converter->start_conversion($file, 'pdf')) {
+ } else if ($plugin->allow_image_conversion() && $mimetype === "image/jpeg") {
+ // Rotates image based on the EXIF value.
+ list ($rotateddata, $size) = $file->rotate_image();
+ if ($rotateddata) {
+ $file = self::save_rotated_image_file($assignment, $userid, $attemptnumber,
+ $rotateddata, $filename);
+ }
+ // Save as PDF file if there is no available converter.
+ if (!$converter->can_convert_format_to('jpg', 'pdf')) {
+ $pdffile = self::save_jpg_to_pdf($assignment, $userid, $attemptnumber, $file, $size);
+ if ($pdffile) {
+ $files[$filename] = $pdffile;
+ }
+ }
+ }
+ // The file has not been converted to PDF, try to convert it to PDF.
+ if (!isset($files[$filename])
+ && $convertedfile = $converter->start_conversion($file, 'pdf')) {
$files[$filename] = $convertedfile;
}
} else if ($converter->can_convert_format_to('html', 'pdf')) {
}
return null;
}
+
+ /**
+ * Convert jpg file to pdf file
+ * @param int|\assign $assignment Assignment
+ * @param int $userid User ID
+ * @param int $attemptnumber Attempt Number
+ * @param \stored_file $file file to save
+ * @param null|array $size size of image
+ * @return \stored_file
+ * @throws \file_exception
+ * @throws \stored_file_creation_exception
+ */
+ private static function save_jpg_to_pdf($assignment, $userid, $attemptnumber, $file, $size=null) {
+ // Temporary file.
+ $filename = $file->get_filename();
+ $tmpdir = make_temp_directory('assignfeedback_editpdf' . DIRECTORY_SEPARATOR
+ . self::TMP_JPG_TO_PDF_FILEAREA . DIRECTORY_SEPARATOR
+ . self::hash($assignment, $userid, $attemptnumber));
+ $tempfile = $tmpdir . DIRECTORY_SEPARATOR . $filename . ".pdf";
+ // Determine orientation.
+ $orientation = 'P';
+ if (!empty($size['width']) && !empty($size['height'])) {
+ if ($size['width'] > $size['height']) {
+ $orientation = 'L';
+ }
+ }
+ // Save JPG image to PDF file.
+ $pdf = new pdf();
+ $pdf->SetHeaderMargin(0);
+ $pdf->SetFooterMargin(0);
+ $pdf->SetMargins(0, 0, 0, true);
+ $pdf->setPrintFooter(false);
+ $pdf->setPrintHeader(false);
+ $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
+ $pdf->AddPage($orientation);
+ $pdf->SetAutoPageBreak(false);
+ // Width has to be define here to fit into A4 page. Otherwise the image will be inserted with original size.
+ if ($orientation == 'P') {
+ $pdf->Image('@' . $file->get_content(), 0, 0, 210);
+ } else {
+ $pdf->Image('@' . $file->get_content(), 0, 0, 297);
+ }
+ $pdf->setPageMark();
+ $pdf->save_pdf($tempfile);
+ $filearea = self::TMP_JPG_TO_PDF_FILEAREA;
+ $pdffile = self::save_file($assignment, $userid, $attemptnumber, $filearea, $tempfile);
+ if (file_exists($tempfile)) {
+ unlink($tempfile);
+ rmdir($tmpdir);
+ }
+ return $pdffile;
+ }
+
+ /**
+ * Save rotated image data to file.
+ * @param int|\assign $assignment Assignment
+ * @param int $userid User ID
+ * @param int $attemptnumber Attempt Number
+ * @param resource $rotateddata image data to save
+ * @param string $filename name of the image file
+ * @return \stored_file
+ * @throws \file_exception
+ * @throws \stored_file_creation_exception
+ */
+ private static function save_rotated_image_file($assignment, $userid, $attemptnumber, $rotateddata, $filename) {
+ $filearea = self::TMP_ROTATED_JPG_FILEAREA;
+ $tmpdir = make_temp_directory('assignfeedback_editpdf' . DIRECTORY_SEPARATOR
+ . $filearea . DIRECTORY_SEPARATOR
+ . self::hash($assignment, $userid, $attemptnumber));
+ $tempfile = $tmpdir . DIRECTORY_SEPARATOR . basename($filename);
+ imagejpeg($rotateddata, $tempfile);
+ $newfile = self::save_file($assignment, $userid, $attemptnumber, $filearea, $tempfile);
+ if (file_exists($tempfile)) {
+ unlink($tempfile);
+ rmdir($tmpdir);
+ }
+ return $newfile;
+ }
+
}