Как я могу визуализировать большие файлы/тысячи страниц, используя преобразование PDF-файлов в буферизованное изображениJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Как я могу визуализировать большие файлы/тысячи страниц, используя преобразование PDF-файлов в буферизованное изображени

Сообщение Anonymous »

Это моя модель документа:

Код: Выделить всё

    public class PdfDocumentModel {
private final PDDocument document;
private float dpi = 110;

// Constructor accepts InputStream
public PdfDocumentModel(InputStream inputStream) throws IOException {
this.document = PDDocument.load(inputStream);  // Load PDF from InputStream
}

public int getPageCount() {
return document.getNumberOfPages();
}

public void close() throws IOException {
document.close();
}

public void setDpi(float dpi) {
this.dpi = dpi;  // Allow setting DPI dynamically for rendering
}

// Render page to temporary file with dynamic DPI control
public synchronized File renderPageToTempFile(int pageIndex) throws IOException {
if (pageIndex < 0 || pageIndex >= getPageCount()) {
throw new IndexOutOfBoundsException("Invalid page index: " + pageIndex);
}

// Render the page to a BufferedImage with the current DPI setting
PDFRenderer renderer = new PDFRenderer(document);
BufferedImage image = renderer.renderImageWithDPI(pageIndex, dpi);  // Use dynamic DPI

// Convert BufferedImage to temporary PNG file
Path tempFilePath = Files.createTempFile("page_" + pageIndex + "_", ".png");
File tempFile = tempFilePath.toFile();

try (OutputStream outputStream = Files.newOutputStream(tempFile.toPath())) {
ImageIO.write(image, "PNG", outputStream);
}

return tempFile;
}

public void deleteTempFile(File tempFile) {
if (tempFile != null && tempFile.exists()) {
boolean deleted = tempFile.delete();
if (!deleted) {
System.err.println("Failed to delete temporary file: " + tempFile.getAbsolutePath());
}
}
}
}

Код: Выделить всё

This is my View model:

Код: Выделить всё

public class CenterViewModel {
private PdfDocumentModel pdfDocument;
private final ListProperty pages = new SimpleListProperty(FXCollections.observableArrayList());
private final IntegerProperty currentPage = new SimpleIntegerProperty();
private final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

public CenterViewModel() {
currentPage.addListener((obs, oldPage, newPage) -> {
if (newPage.intValue() >= 0 && newPage.intValue() < pages.size()) {
loadPage(newPage.intValue());
}
});
}

public void loadPdf(InputStream inputStream) throws IOException {
// Close the existing PDF document if one is already loaded
if (pdfDocument != null) {
closePdf();
}

// Create a new PdfDocumentModel using the InputStream
pdfDocument = new PdfDocumentModel(inputStream);

// Clear previous page list and prepare for new pages
pages.clear();
int pageCount = pdfDocument.getPageCount();

// Add placeholders for each page
for (int i = 0; i < pageCount; i++) {
pages.add(null);  // Placeholder for each page
}

// Load a subset of pages initially (e.g., first 100 pages)
loadPages(0, Math.min(pageCount, 2000));
}

public void setDpi(float dpi) {
pdfDocument.setDpi(dpi);
}

public void loadPages(int startIndex, int endIndex) {
for (int i = startIndex; i < endIndex; i++) {
if (i >= pages.size() || pages.get(i) != null) {
continue;
}
loadPage(i);
}
}

public void loadPage(int pageIndex) {
if (pageIndex < 0 || pageIndex >= pages.size()) {
throw new IndexOutOfBoundsException("Invalid page index: " + pageIndex);
}

// Render page asynchronously
Task  task = new Task() {
@Override
protected File call() throws Exception {
return pdfDocument.renderPageToTempFile(pageIndex);
}

@Override
protected void succeeded() {
File tempFile = getValue();
try {
BufferedImage image = ImageIO.read(tempFile);
pages.set(pageIndex, image);  // Update page image
pdfDocument.deleteTempFile(tempFile);  // Clean up temporary file
} catch (IOException e) {
System.err.println("Failed to read page " + pageIndex + ": " + e.getMessage());
}
}

@Override
protected void failed() {
System.err.println("Failed to render page " + pageIndex + ": " + getException().getMessage());
}
};
executorService.submit(task);
}

public void shutdownExecutor() {
if (!executorService.isShutdown()) {
executorService.shutdown();
}
}

public int getTotalPages() {
return pdfDocument != null ? pdfDocument.getPageCount() : 0;
}

public ListProperty pagesProperty() {
return pages;
}

public IntegerProperty currentPageProperty() {
return currentPage;
}

public void setCurrentPage(int pageIndex) {
if (pageIndex >= 0 && pageIndex < pages.size()) {
currentPage.set(pageIndex);
}
}

public void closePdf() throws IOException {
if (pdfDocument != null) {
pdfDocument.close();
}
pages.clear();
}
}
А это вид:

Код: Выделить всё

    public class CenterView {
private final ListView listView;
private final ListProperty pages = new SimpleListProperty(FXCollections.observableArrayList());
private final CenterViewModel centerViewModel = new CenterViewModel();
private final IntegerProperty currentPage = new SimpleIntegerProperty();
private final Label totalPagesLabel = new Label();
private final Button resetButton = new Button("Reset");
private final BorderPane mainLayout = new BorderPane();

public CenterView() {
listView = new ListView(centerViewModel.pagesProperty());
listView.getStylesheets().add(Objects.requireNonNull(getClass().getResource("/style/listview-config.css")).toExternalForm());
initialize();
}

private void initialize() {
listView.setCellFactory(param -> new PdfPageCell());
currentPage.addListener((obs, oldVal, newVal) -> loadPagesAround(newVal.intValue()));

listView.setOnDragOver(this::handleDragOver);
listView.setOnDragDropped(this::handleDragDropped);

resetButton.setOnAction(event -> {
pages.clear();
totalPagesLabel.setText("Total Pages: 0");
});

listView.setOnScroll(event -> {
int currentIndex = listView.getSelectionModel().getSelectedIndex();
if (event.getDeltaY() > 0 && currentIndex > 0) {
loadPagesAround(currentIndex - 5);
} else if (event.getDeltaY() < 0 && currentIndex < pages.size() - 1) {
loadPagesAround(currentIndex + 5);
}
});

listView.getSelectionModel().selectedIndexProperty().addListener((obs, oldSelection, newSelection) -> {
if (newSelection != null && newSelection.intValue() >= 0) {
loadPagesAround(newSelection.intValue());
}
});

mainLayout.setTop(resetButton);
mainLayout.setCenter(listView);
mainLayout.setBottom(totalPagesLabel);
totalPagesLabel.setStyle("-fx-padding: 10px;");
}

private class PdfPageCell extends ListCell {
private final StackPane stackPane = new StackPane();
private final ImageView imageView = new ImageView();
private final DropShadow dropShadow = new DropShadow();  // DropShadow instance

public PdfPageCell() {
dropShadow.setOffsetX(0);
dropShadow.setOffsetY(0);
dropShadow.setRadius(7);
dropShadow.setSpread(0.1);
dropShadow.setColor(Color.gray(0.1));

imageView.setEffect(dropShadow);

stackPane.getChildren().add(imageView);
imageView.setPreserveRatio(true);
imageView.setSmooth(true);
}

@Override
protected void updateItem(BufferedImage item, boolean empty) {
super.updateItem(item, empty);

if (empty || item == null) {
setGraphic(null);
} else {
// Convert the BufferedImage to JavaFX Image
imageView.setImage(SwingFXUtils.toFXImage(item, null));

// Set the ImageView to fill the entire cell size
imageView.fitWidthProperty().bind(stackPane.widthProperty());
imageView.fitHeightProperty().bind(stackPane.heightProperty());

setGraphic(stackPane);
}
}
}

public BorderPane getView() {
updateTotalPages();
return mainLayout;
}

private void loadPagesAround(int currentIndex) {
int totalPages = centerViewModel.getTotalPages();
int startIndex = Math.max(currentIndex - 5, 0);
int endIndex = Math.min(currentIndex + 5, totalPages - 1);

// Asynchronously preload pages
new Thread(() -> {
for (int i = startIndex; i 

Подробнее здесь: [url]https://stackoverflow.com/questions/79372952/how-can-i-render-large-files-thousand-of-pages-using-the-conversion-of-pdf-file[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»