2023-07-09 00:05:33 +01:00
package stirling.software.SPDF.controller.api ;
import java.io.ByteArrayInputStream ;
import java.io.ByteArrayOutputStream ;
import java.io.IOException ;
2023-09-03 01:24:02 +01:00
import org.apache.pdfbox.multipdf.LayerUtility ;
2023-09-02 20:32:44 +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 ;
2023-09-02 20:32:44 +01:00
import org.apache.pdfbox.pdmodel.common.PDRectangle ;
2023-09-03 01:24:02 +01:00
import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject ;
2023-07-09 00:05:33 +01: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-07-09 00:05:33 +01:00
import org.springframework.web.bind.annotation.PostMapping ;
2023-09-11 23:19:50 +01:00
import org.springframework.web.bind.annotation.RequestMapping ;
2023-07-09 00:05:33 +01:00
import org.springframework.web.bind.annotation.RestController ;
import io.swagger.v3.oas.annotations.Operation ;
import io.swagger.v3.oas.annotations.tags.Tag ;
2023-09-09 00:25:27 +01:00
import stirling.software.SPDF.model.api.general.CropPdfForm ;
2023-07-09 00:05:33 +01:00
import stirling.software.SPDF.utils.WebResponseUtils ;
@RestController
2023-09-11 23:19:50 +01:00
@RequestMapping ( "/api/v1/general" )
2023-07-09 00:05:33 +01:00
@Tag ( name = "General" , description = "General APIs" )
public class CropController {
2023-09-02 20:32:44 +01:00
private static final Logger logger = LoggerFactory . getLogger ( CropController . class );
2023-07-09 00:05:33 +01:00
@PostMapping ( value = "/crop" , consumes = "multipart/form-data" )
@Operation ( summary = "Crops a PDF document" , description = "This operation takes an input PDF file and crops it according to the given coordinates. Input:PDF Output:PDF Type:SISO" )
2023-09-09 00:25:27 +01:00
public ResponseEntity < byte []> cropPdf ( @ModelAttribute CropPdfForm form )
2023-09-02 20:32:44 +01:00
throws IOException {
2023-09-09 00:25:27 +01:00
2023-09-02 20:32:44 +01:00
2023-09-09 00:25:27 +01:00
PDDocument sourceDocument = PDDocument . load ( new ByteArrayInputStream ( form . getFileInput (). getBytes ()));
2023-09-02 20:32:44 +01:00
PDDocument newDocument = new PDDocument ();
int totalPages = sourceDocument . getNumberOfPages ();
LayerUtility layerUtility = new LayerUtility ( newDocument );
for ( int i = 0 ; i < totalPages ; i ++ ) {
PDPage sourcePage = sourceDocument . getPage ( i );
// Create a new page with the size of the source page
PDPage newPage = new PDPage ( sourcePage . getMediaBox ());
newDocument . addPage ( newPage );
PDPageContentStream contentStream = new PDPageContentStream ( newDocument , newPage );
// Import the source page as a form XObject
PDFormXObject formXObject = layerUtility . importPageAsForm ( sourceDocument , i );
contentStream . saveGraphicsState ();
// Define the crop area
2023-09-09 00:25:27 +01:00
contentStream . addRect ( form . getX (), form . getY (), form . getWidth (), form . getHeight ());
2023-09-02 20:32:44 +01:00
contentStream . clip ();
// Draw the entire formXObject
contentStream . drawForm ( formXObject );
contentStream . restoreGraphicsState ();
contentStream . close ();
// Now, set the new page's media box to the cropped size
2023-09-09 00:25:27 +01:00
newPage . setMediaBox ( new PDRectangle ( form . getX (), form . getY (), form . getWidth (), form . getHeight ()));
2023-09-02 20:32:44 +01:00
}
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
newDocument . save ( baos );
newDocument . close ();
sourceDocument . close ();
byte [] pdfContent = baos . toByteArray ();
2023-09-09 00:25:27 +01:00
return WebResponseUtils . bytesToWebResponse ( pdfContent , form . getFileInput (). getOriginalFilename (). replaceFirst ( "[.][^.]+$" , "" ) + "_cropped.pdf" );
2023-07-09 00:05:33 +01:00
}
}