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
}