MDL-75295 assignfeedback_editpdf: Convert PDF to png at once

This commit is contained in:
Tomo Tsuyuki
2022-09-16 19:31:05 +10:00
parent b077af7e89
commit 260cc864cf
2 changed files with 85 additions and 19 deletions
@@ -438,9 +438,13 @@ EOD;
$fs->delete_area_files($record->contextid, $record->component, $record->filearea, $record->itemid);
$files = array();
$images = $pdf->get_images();
for ($i = 0; $i < $pagecount; $i++) {
try {
$image = $pdf->get_image($i);
if (empty($images[$i])) {
throw new \moodle_exception('error image');
}
$image = $images[$i];
if (!$resetrotation) {
$pagerotation = page_editor::get_page_rotation($grade->id, $i);
$degree = !empty($pagerotation) ? $pagerotation->degree : 0;
+80 -18
View File
@@ -528,6 +528,38 @@ class pdf extends TcpdfFpdi {
$this->imagefolder = $folder;
}
/**
* Generate images from the PDF
* @return array Array of filename of the generated images
*/
public function get_images(): array {
$this->precheck_generate_image();
$imagefile = $this->imagefolder . '/' . self::IMAGE_PAGE;
$command = $this->get_command_for_image(-1, $imagefile);
exec($command);
$images = array();
for ($i = 0; $i < $this->pagecount; $i++) {
// Image file is created from 1, so need to change to 0.
$file = $imagefile . ($i + 1) . '.png';
$newfile = $imagefile . $i . '.png';
if (file_exists($file)) {
rename($file, $newfile);
} else {
// Converter added '-' and zerofill for the pagenumber.
$length = strlen($this->pagecount);
$file = $imagefile . '-' . str_pad(($i + 1), $length, '0', STR_PAD_LEFT) . '.png';
if (file_exists($file)) {
rename($file, $newfile);
} else {
$newfile = self::get_error_image($this->imagefolder, $i);
}
}
$images[$i] = basename($newfile);
}
return $images;
}
/**
* Generate an image of the specified page in the PDF
* @param int $pageno the page to generate the image of
@@ -536,17 +568,7 @@ class pdf extends TcpdfFpdi {
* @return string the filename of the generated image
*/
public function get_image($pageno) {
if (!$this->filename) {
throw new \coding_exception('Attempting to generate a page image without first setting the PDF filename');
}
if (!$this->imagefolder) {
throw new \coding_exception('Attempting to generate a page image without first specifying the image output folder');
}
if (!is_dir($this->imagefolder)) {
throw new \coding_exception('The specified image output folder is not a valid folder');
}
$this->precheck_generate_image();
$imagefile = $this->imagefolder . '/' . self::IMAGE_PAGE . $pageno . '.png';
$generate = true;
@@ -575,10 +597,29 @@ class pdf extends TcpdfFpdi {
return self::IMAGE_PAGE . $pageno . '.png';
}
/**
* Make sure the file name and image folder are ready before generate image.
* @return bool
*/
protected function precheck_generate_image() {
if (!$this->filename) {
throw new \coding_exception('Attempting to generate a page image without first setting the PDF filename');
}
if (!$this->imagefolder) {
throw new \coding_exception('Attempting to generate a page image without first specifying the image output folder');
}
if (!is_dir($this->imagefolder)) {
throw new \coding_exception('The specified image output folder is not a valid folder');
}
return true;
}
/**
* Gets the command to use to extract as image the given $pageno page number
* from a PDF document into the $imagefile file.
* @param int $pageno Page number to extract from document.
* @param int $pageno Page number to extract from document. -1 means for all pages.
* @param string $imagefile Target filename for the PNG image as absolute path.
* @return string The command to use to extract a page as PNG image.
*/
@@ -597,7 +638,7 @@ class pdf extends TcpdfFpdi {
/**
* Gets the pdftoppm command to use to extract as image the given $pageno page number
* from a PDF document into the $imagefile file.
* @param int $pageno Page number to extract from document.
* @param int $pageno Page number to extract from document. -1 means for all pages.
* @param string $imagefile Target filename for the PNG image as absolute path.
* @return string The pdftoppm command to use to extract a page as PNG image.
*/
@@ -605,17 +646,28 @@ class pdf extends TcpdfFpdi {
global $CFG;
$pdftoppmexec = \escapeshellarg($CFG->pathtopdftoppm);
$imageres = \escapeshellarg(100);
$imagefile = substr($imagefile, 0, -4); // Pdftoppm tool automatically adds extension file.
$imagefilearg = \escapeshellarg($imagefile);
$filename = \escapeshellarg($this->filename);
$pagenoinc = \escapeshellarg($pageno + 1);
return "$pdftoppmexec -q -r $imageres -f $pagenoinc -l $pagenoinc -png -singlefile $filename $imagefilearg";
if ($pageno >= 0) {
// Convert 1 page.
$imagefile = substr($imagefile, 0, -4); // Pdftoppm tool automatically adds extension file.
$frompageno = $pagenoinc;
$topageno = $pagenoinc;
$singlefile = '-singlefile';
} else {
// Convert all pages at once.
$frompageno = 1;
$topageno = $this->pagecount;
$singlefile = '';
}
$imagefilearg = \escapeshellarg($imagefile);
return "$pdftoppmexec -q -r $imageres -f $frompageno -l $topageno -png $singlefile $filename $imagefilearg";
}
/**
* Gets the ghostscript (gs) command to use to extract as image the given $pageno page number
* from a PDF document into the $imagefile file.
* @param int $pageno Page number to extract from document.
* @param int $pageno Page number to extract from document. -1 means for all pages.
* @param string $imagefile Target filename for the PNG image as absolute path.
* @return string The ghostscript (gs) command to use to extract a page as PNG image.
*/
@@ -626,7 +678,17 @@ class pdf extends TcpdfFpdi {
$imagefilearg = \escapeshellarg($imagefile);
$filename = \escapeshellarg($this->filename);
$pagenoinc = \escapeshellarg($pageno + 1);
return "$gsexec -q -sDEVICE=png16m -dSAFER -dBATCH -dNOPAUSE -r$imageres -dFirstPage=$pagenoinc -dLastPage=$pagenoinc ".
if ($pageno >= 0) {
// Convert 1 page.
$firstpage = $pagenoinc;
$lastpage = $pagenoinc;
} else {
// Convert all pages at once.
$imagefilearg = \escapeshellarg($imagefile . '%d.png');
$firstpage = 1;
$lastpage = $this->pagecount;
}
return "$gsexec -q -sDEVICE=png16m -dSAFER -dBATCH -dNOPAUSE -r$imageres -dFirstPage=$firstpage -dLastPage=$lastpage ".
"-dDOINTERPOLATE -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -sOutputFile=$imagefilearg $filename";
}