-
-
Notifications
You must be signed in to change notification settings - Fork 156
Tutorial 05 Images
Dries Horions edited this page Feb 13, 2026
·
1 revision
This tutorial demonstrates:
- Adding images to table cells
- Image scaling to fit cells
- Image padding control
- Multiple images in a table
- Different image sizes and aspect ratios
View Source on GitHub | Download PDF

package be.quodlibet.boxable.tutorial;
import be.quodlibet.boxable.BaseTable;
import be.quodlibet.boxable.Cell;
import be.quodlibet.boxable.HorizontalAlignment;
import be.quodlibet.boxable.ImageCell;
import be.quodlibet.boxable.Row;
import be.quodlibet.boxable.image.Image;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.font.Standard14Fonts;
import org.junit.Test;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* Tutorial 05: Images in Cells
*
* This tutorial demonstrates:
* - Adding images to table cells
* - Image scaling to fit cells
* - Image padding control
* - Multiple images in a table
* - Different image sizes and aspect ratios
*/
public class Tutorial05_Images {
@Test
public void demonstrateImages() throws IOException {
// Initialize PDF Document
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// Define table dimensions
float margin = 50;
float yStart = page.getMediaBox().getHeight() - margin;
float tableWidth = page.getMediaBox().getWidth() - (2 * margin);
float yStartNewPage = page.getMediaBox().getHeight() - margin;
float bottomMargin = 70;
// Create the table
BaseTable table = new BaseTable(yStart, yStartNewPage, bottomMargin,
tableWidth, margin, document, page,
true, true);
// Title Row
Row<PDPage> titleRow = table.createRow(30f);
Cell<PDPage> titleCell = titleRow.createCell(100, "Tutorial 05: Images in Cells");
titleCell.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD));
titleCell.setFontSize(16f);
titleCell.setFillColor(new Color(26, 188, 156)); // Teal background
titleCell.setTextColor(Color.WHITE);
titleCell.setAlign(HorizontalAlignment.CENTER);
// Description
Row<PDPage> descRow = table.createRow(20f);
Cell<PDPage> descCell = descRow.createCell(100,
"Learn how to add images to cells, control scaling, and adjust padding.");
descCell.setFillColor(new Color(236, 240, 241));
descCell.setAlign(HorizontalAlignment.CENTER);
// Section 1: Basic Image in Cell
addSectionHeader(table, "Basic Image in Cell");
Row<PDPage> basicDesc = table.createRow(15f);
basicDesc.createCell(100, "A simple image in a cell with default settings:");
// Create a sample image (red background with green circle)
BufferedImage redGreenImage = createSampleImage(200, 100, Color.RED, Color.GREEN);
Image image1 = new Image(redGreenImage);
Row<PDPage> imageRow1 = table.createRow(100f);
ImageCell<PDPage> imageCell1 = imageRow1.createImageCell(100, image1);
imageCell1.setAlign(HorizontalAlignment.CENTER);
// Section 2: Image Scaling
addSectionHeader(table, "Image Scaling");
Row<PDPage> scalingHeader = table.createRow(15f);
scalingHeader.createCell(33.33f, "Small Cell");
scalingHeader.createCell(33.33f, "Medium Cell");
scalingHeader.createCell(33.34f, "Large Cell");
styleHeaderRow(scalingHeader);
Row<PDPage> scalingRow = table.createRow(80f);
// Small cell with image
BufferedImage blueImage = createSampleImage(200, 100, Color.BLUE, Color.YELLOW);
Image image2 = new Image(blueImage);
ImageCell<PDPage> smallCell = scalingRow.createImageCell(33.33f, image2);
smallCell.setAlign(HorizontalAlignment.CENTER);
// Medium cell with image
BufferedImage orangeImage = createSampleImage(200, 100, Color.ORANGE, Color.CYAN);
Image image3 = new Image(orangeImage);
ImageCell<PDPage> mediumCell = scalingRow.createImageCell(33.33f, image3);
mediumCell.setAlign(HorizontalAlignment.CENTER);
// Large cell with image
BufferedImage purpleImage = createSampleImage(200, 100, new Color(155, 89, 182), Color.WHITE);
Image image4 = new Image(purpleImage);
ImageCell<PDPage> largeCell = scalingRow.createImageCell(33.34f, image4);
largeCell.setAlign(HorizontalAlignment.CENTER);
// Section 3: Image Padding Control
addSectionHeader(table, "Image Padding Control");
Row<PDPage> paddingDesc = table.createRow(15f);
paddingDesc.createCell(100, "Control the padding around images:");
Row<PDPage> paddingHeader = table.createRow(15f);
paddingHeader.createCell(33.33f, "Default Padding");
paddingHeader.createCell(33.33f, "No Padding");
paddingHeader.createCell(33.34f, "Custom Padding");
styleHeaderRow(paddingHeader);
Row<PDPage> paddingRow = table.createRow(80f);
// Default padding
BufferedImage greenImage = createSampleImage(200, 100, new Color(46, 204, 113), Color.BLACK);
Image image5 = new Image(greenImage);
ImageCell<PDPage> defaultPadCell = paddingRow.createImageCell(33.33f, image5);
defaultPadCell.setFillColor(new Color(236, 240, 241));
// No padding
BufferedImage yellowImage = createSampleImage(200, 100, new Color(241, 196, 15), Color.BLACK);
Image image6 = new Image(yellowImage);
ImageCell<PDPage> noPadCell = paddingRow.createImageCell(33.33f, image6);
noPadCell.setTopPadding(0);
noPadCell.setBottomPadding(0);
noPadCell.setLeftPadding(0);
noPadCell.setRightPadding(0);
noPadCell.setFillColor(new Color(236, 240, 241));
// Custom padding (20pt)
BufferedImage cyanImage = createSampleImage(200, 100, new Color(52, 152, 219), Color.WHITE);
Image image7 = new Image(cyanImage);
ImageCell<PDPage> customPadCell = paddingRow.createImageCell(33.34f, image7);
customPadCell.setTopPadding(20);
customPadCell.setBottomPadding(20);
customPadCell.setLeftPadding(20);
customPadCell.setRightPadding(20);
customPadCell.setFillColor(new Color(236, 240, 241));
// Section 4: Different Image Aspect Ratios
addSectionHeader(table, "Different Image Aspect Ratios");
Row<PDPage> aspectHeader = table.createRow(15f);
aspectHeader.createCell(33.33f, "Landscape (2:1)");
aspectHeader.createCell(33.33f, "Square (1:1)");
aspectHeader.createCell(33.34f, "Portrait (1:2)");
styleHeaderRow(aspectHeader);
Row<PDPage> aspectRow = table.createRow(100f);
// Landscape image
BufferedImage landscapeImage = createSampleImage(200, 100, new Color(231, 76, 60), Color.WHITE);
Image image8 = new Image(landscapeImage);
ImageCell<PDPage> landscapeCell = aspectRow.createImageCell(33.33f, image8);
landscapeCell.setAlign(HorizontalAlignment.CENTER);
// Square image
BufferedImage squareImage = createSampleImage(150, 150, new Color(52, 73, 94), Color.WHITE);
Image image9 = new Image(squareImage);
ImageCell<PDPage> squareCell = aspectRow.createImageCell(33.33f, image9);
squareCell.setAlign(HorizontalAlignment.CENTER);
// Portrait image
BufferedImage portraitImage = createSampleImage(100, 200, new Color(155, 89, 182), Color.WHITE);
Image image10 = new Image(portraitImage);
ImageCell<PDPage> portraitCell = aspectRow.createImageCell(33.34f, image10);
portraitCell.setAlign(HorizontalAlignment.CENTER);
// Section 5: Images with Text
addSectionHeader(table, "Images Combined with Text");
Row<PDPage> combinedRow = table.createRow(80f);
// Image cell
BufferedImage finalImage = createSampleImage(200, 100, new Color(41, 128, 185), Color.WHITE);
Image image11 = new Image(finalImage);
ImageCell<PDPage> imgCell = combinedRow.createImageCell(40f, image11);
imgCell.setAlign(HorizontalAlignment.CENTER);
// Text description cell
Cell<PDPage> textCell = combinedRow.createCell(60f,
"<b>Product Name:</b> Sample Widget<br/>" +
"<b>Description:</b> This is a high-quality product with excellent features.<br/>" +
"<b>Price:</b> $99.99<br/>" +
"<b>Stock:</b> In Stock");
textCell.setAlign(HorizontalAlignment.LEFT);
// Draw the table
table.draw();
// Save the document
File file = new File("target/tutorials/Tutorial05_Images.pdf");
System.out.println("Tutorial 05 PDF saved at: " + file.getAbsolutePath());
file.getParentFile().mkdirs();
document.save(file);
document.close();
}
/**
* Helper method to create a sample image with colored background and shape
*/
private BufferedImage createSampleImage(int width, int height, Color bgColor, Color shapeColor) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
// Fill background
g.setColor(bgColor);
g.fillRect(0, 0, width, height);
// Draw a circle or oval
g.setColor(shapeColor);
int size = Math.min(width, height);
int x = (width - size) / 2;
int y = (height - size) / 2;
g.fillOval(x, y, size, size);
g.dispose();
return image;
}
/**
* Helper method to add a section header
*/
private void addSectionHeader(BaseTable table, String title) throws IOException {
Row<PDPage> sectionRow = table.createRow(18f);
Cell<PDPage> sectionCell = sectionRow.createCell(100, title);
sectionCell.setFillColor(new Color(44, 62, 80));
sectionCell.setTextColor(Color.WHITE);
sectionCell.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD));
sectionCell.setAlign(HorizontalAlignment.CENTER);
}
/**
* Helper method to style header rows
*/
private void styleHeaderRow(Row<PDPage> row) {
Color headerColor = new Color(52, 73, 94);
for (Cell<PDPage> cell : row.getCells()) {
cell.setFillColor(headerColor);
cell.setTextColor(Color.WHITE);
cell.setFont(new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD));
}
}
}Special thanks to :
=======
Copyright 2026
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.