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 ;
import org.springframework.web.bind.annotation.PostMapping ;
import org.springframework.web.bind.annotation.RequestParam ;
import org.springframework.web.bind.annotation.RestController ;
import org.springframework.web.multipart.MultipartFile ;
import io.swagger.v3.oas.annotations.Operation ;
import io.swagger.v3.oas.annotations.Parameter ;
import io.swagger.v3.oas.annotations.media.Schema ;
import io.swagger.v3.oas.annotations.tags.Tag ;
import stirling.software.SPDF.utils.WebResponseUtils ;
@RestController
@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" )
public ResponseEntity < byte []> cropPdf (
2023-09-02 20:32:44 +01:00
@Parameter ( description = "The input PDF file" , required = true ) @RequestParam ( "fileInput" ) MultipartFile file ,
@Parameter ( description = "The x-coordinate of the top-left corner of the crop area" , required = true , schema = @Schema ( type = "number" )) @RequestParam ( "x" ) float x ,
@Parameter ( description = "The y-coordinate of the top-left corner of the crop area" , required = true , schema = @Schema ( type = "number" )) @RequestParam ( "y" ) float y ,
@Parameter ( description = "The width of the crop area" , required = true , schema = @Schema ( type = "number" )) @RequestParam ( "width" ) float width ,
@Parameter ( description = "The height of the crop area" , required = true , schema = @Schema ( type = "number" )) @RequestParam ( "height" ) float height )
throws IOException {
PDDocument sourceDocument = PDDocument . load ( new ByteArrayInputStream ( file . getBytes ()));
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
contentStream . addRect ( x , y , width , height );
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
newPage . setMediaBox ( new PDRectangle ( x , y , width , height ));
}
ByteArrayOutputStream baos = new ByteArrayOutputStream ();
newDocument . save ( baos );
newDocument . close ();
sourceDocument . close ();
byte [] pdfContent = baos . toByteArray ();
return WebResponseUtils . bytesToWebResponse ( pdfContent , file . getOriginalFilename (). replaceFirst ( "[.][^.]+$" , "" ) + "_cropped.pdf" );
2023-07-09 00:05:33 +01:00
}
}