2023-05-31 21:33:45 +01:00
package stirling.software.SPDF.controller.api ;
2023-05-31 21:39:40 +02:00
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
2023-06-03 22:56:15 +01:00
import java.util.HashMap ;
import java.util.Map ;
2023-05-31 21:39:40 +02:00
2023-09-03 01:24:02 +01:00
import org.apache.pdfbox.multipdf.LayerUtility ;
2023-09-02 20:21:55 +01:00
import org.apache.pdfbox.pdmodel.PDDocument ;
import org.apache.pdfbox.pdmodel.PDPage ;
2023-09-03 01:24:02 +01:00
import org.apache.pdfbox.pdmodel.PDPageContentStream ;
import org.apache.pdfbox.pdmodel.common.PDRectangle ;
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject ;
2023-09-02 20:21:55 +01:00
import org.apache.pdfbox.util.Matrix ;
2023-05-31 21:39:40 +02:00
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import org.springframework.http.ResponseEntity ;
2023-09-09 00:25:27 +01:00
import org.springframework.web.bind.annotation.ModelAttribute ;
2023-05-31 21:39:40 +02:00
import org.springframework.web.bind.annotation.PostMapping ;
2023-09-11 23:19:50 +01:00
import org.springframework.web.bind.annotation.RequestMapping ;
2023-05-31 21:39:40 +02:00
import org.springframework.web.bind.annotation.RestController ;
import org.springframework.web.multipart.MultipartFile ;
import io.swagger.v3.oas.annotations.Operation ;
2023-06-25 09:16:32 +01:00
import io.swagger.v3.oas.annotations.tags.Tag ;
2023-09-09 00:25:27 +01:00
import stirling.software.SPDF.model.api.general.ScalePagesRequest ;
2023-05-31 21:33:45 +01:00
import stirling.software.SPDF.utils.WebResponseUtils ;
2023-05-31 21:39:40 +02:00
@RestController
2023-09-11 23:19:50 +01:00
@RequestMapping ( "/api/v1/general" )
2023-06-25 09:16:32 +01:00
@Tag ( name = "General" , description = "General APIs" )
2023-05-31 21:39:40 +02:00
public class ScalePagesController {
private static final Logger logger = LoggerFactory . getLogger ( ScalePagesController . class );
@PostMapping ( value = "/scale-pages" , consumes = "multipart/form-data" )
2023-06-23 23:29:53 +01:00
@Operation ( summary = "Change the size of a PDF page/document" , description = "This operation takes an input PDF file and the size to scale the pages to in the output PDF file. Input:PDF Output:PDF Type:SISO" )
2023-09-09 00:25:27 +01:00
public ResponseEntity < byte []> scalePages ( @ModelAttribute ScalePagesRequest request ) throws IOException {
MultipartFile file = request . getFileInput ();
2023-09-13 00:46:30 +01:00
String targetPDRectangle = request . getPageSize ();
2023-09-09 00:25:27 +01:00
float scaleFactor = request . getScaleFactor ();
2023-06-01 21:37:33 +01:00
2023-09-02 20:21:55 +01:00
Map < String , PDRectangle > sizeMap = new HashMap <> ();
2023-06-04 22:40:14 +01:00
// Add A0 - A10
2023-09-02 20:21:55 +01:00
sizeMap . put ( "A0" , PDRectangle . A0 );
sizeMap . put ( "A1" , PDRectangle . A1 );
sizeMap . put ( "A2" , PDRectangle . A2 );
sizeMap . put ( "A3" , PDRectangle . A3 );
sizeMap . put ( "A4" , PDRectangle . A4 );
sizeMap . put ( "A5" , PDRectangle . A5 );
sizeMap . put ( "A6" , PDRectangle . A6 );
2023-06-04 22:40:14 +01:00
// Add other sizes
2023-09-02 20:21:55 +01:00
sizeMap . put ( "LETTER" , PDRectangle . LETTER );
sizeMap . put ( "LEGAL" , PDRectangle . LEGAL );
2023-06-04 22:40:14 +01:00
2023-09-02 20:21:55 +01:00
if ( ! sizeMap . containsKey ( targetPDRectangle )) {
2023-06-04 22:40:14 +01:00
throw new IllegalArgumentException (
2023-09-02 20:21:55 +01:00
"Invalid PDRectangle. It must be one of the following: A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10" );
2023-05-31 21:39:40 +02:00
}
2023-09-02 20:21:55 +01:00
PDRectangle targetSize = sizeMap . get ( targetPDRectangle );
PDDocument sourceDocument = PDDocument . load ( file . getBytes ());
PDDocument outputDocument = new PDDocument ();
int totalPages = sourceDocument . getNumberOfPages ();
for ( int i = 0 ; i < totalPages ; i ++ ) {
PDPage sourcePage = sourceDocument . getPage ( i );
PDRectangle sourceSize = sourcePage . getMediaBox ();
float scaleWidth = targetSize . getWidth () / sourceSize . getWidth ();
float scaleHeight = targetSize . getHeight () / sourceSize . getHeight ();
float scale = Math . min ( scaleWidth , scaleHeight ) * scaleFactor ;
PDPage newPage = new PDPage ( targetSize );
outputDocument . addPage ( newPage );
PDPageContentStream contentStream = new PDPageContentStream ( outputDocument , newPage , PDPageContentStream . AppendMode . APPEND , true );
float x = ( targetSize . getWidth () - sourceSize . getWidth () * scale ) / 2 ;
float y = ( targetSize . getHeight () - sourceSize . getHeight () * scale ) / 2 ;
contentStream . saveGraphicsState ();
contentStream . transform ( Matrix . getTranslateInstance ( x , y ));
contentStream . transform ( Matrix . getScaleInstance ( scale , scale ));
LayerUtility layerUtility = new LayerUtility ( outputDocument );
PDFormXObject form = layerUtility . importPageAsForm ( sourceDocument , i );
contentStream . drawForm ( form );
contentStream . restoreGraphicsState ();
contentStream . close ();
}
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
outputDocument . save ( baos );
outputDocument . close ();
sourceDocument . close ();
return WebResponseUtils . bytesToWebResponse ( baos . toByteArray (),
2023-06-04 22:40:14 +01:00
file . getOriginalFilename (). replaceFirst ( "[.][^.]+$" , "" ) + "_scaled.pdf" );
2023-05-31 21:39:40 +02:00
}
2023-06-03 22:56:15 +01:00
2023-05-31 21:39:40 +02:00
}