bb6cc6e241
- lib/java/: Java renderer (JrxmlRenderer) using JasperReports 6.21.0 - JrxmlDebug for diagnostics, JrxmlGen for format reference - download_jars.sh for one-time dependency setup - agent/nodes.py: _render_jrxml_to_png() and _compute_pixel_similarity() - Pixel comparison integrates into validate node (SSIM < 0.4 fails) - Pixel fidelity context injected into correct_jrxml for targeted fixes - tests/test_pixel_comparison.py: 15 unit tests (render, SSIM, integration) - .gitignore: exclude lib/java/*.jar, lib/java/*.class, tmp/ - CLAUDE.md: v11 changelog documenting the rendering pipeline - All non-LLM tests pass (97/97)
111 lines
4.2 KiB
Java
111 lines
4.2 KiB
Java
import net.sf.jasperreports.engine.*;
|
|
import net.sf.jasperreports.engine.export.*;
|
|
import net.sf.jasperreports.export.*;
|
|
import java.io.*;
|
|
import java.util.*;
|
|
import java.awt.image.*;
|
|
import javax.imageio.*;
|
|
|
|
/**
|
|
* Minimal JRXML → PNG renderer for pixel-level fidelity comparison.
|
|
* Usage: java JrxmlRenderer input.jrxml output.png [scale]
|
|
* scale: optional zoom factor (default 2.0 for readable text)
|
|
*
|
|
* Uses JasperReports 7.x exporter API (SimpleExporterInput / SimpleGraphics2DExporterOutput).
|
|
*/
|
|
public class JrxmlRenderer {
|
|
public static void main(String[] args) throws Exception {
|
|
if (args.length < 2) {
|
|
System.err.println("Usage: java JrxmlRenderer <input.jrxml> <output.png> [scale]");
|
|
System.exit(1);
|
|
}
|
|
|
|
String jrxmlPath = args[0];
|
|
String outputPath = args[1];
|
|
float scale = args.length >= 3 ? Float.parseFloat(args[2]) : 2.0f;
|
|
|
|
File jrxmlFile = new File(jrxmlPath);
|
|
if (!jrxmlFile.exists()) {
|
|
System.err.println("ERROR: JRXML file not found: " + jrxmlPath);
|
|
System.exit(2);
|
|
}
|
|
|
|
try {
|
|
// 1. Compile JRXML → JasperReport
|
|
JasperReport report = JasperCompileManager.compileReport(jrxmlPath);
|
|
|
|
// 2. Fill with empty data source
|
|
Map<String, Object> params = new HashMap<>();
|
|
JasperPrint print = JasperFillManager.fillReport(report, params, new JREmptyDataSource());
|
|
|
|
int pages = print.getPages().size();
|
|
if (pages == 0) {
|
|
System.err.println("ERROR: Report has 0 pages after filling");
|
|
System.exit(4);
|
|
}
|
|
|
|
// 3. Calculate image dimensions from page size
|
|
// JasperReports uses 72 DPI, convert to pixels with scale
|
|
int pageWidth = (int) Math.ceil(report.getPageWidth() * scale);
|
|
int pageHeight = (int) Math.ceil(report.getPageHeight() * scale);
|
|
|
|
// 4. Render each page to a BufferedImage
|
|
java.util.List<BufferedImage> pageImages = new ArrayList<>();
|
|
|
|
for (int i = 0; i < pages; i++) {
|
|
BufferedImage pageImage = new BufferedImage(pageWidth, pageHeight, BufferedImage.TYPE_INT_RGB);
|
|
java.awt.Graphics2D g2d = pageImage.createGraphics();
|
|
g2d.setColor(java.awt.Color.WHITE);
|
|
g2d.fillRect(0, 0, pageWidth, pageHeight);
|
|
// Scale the graphics context
|
|
g2d.scale(scale, scale);
|
|
|
|
JRGraphics2DExporter exporter = new JRGraphics2DExporter();
|
|
exporter.setExporterInput(new SimpleExporterInput(print));
|
|
|
|
SimpleGraphics2DExporterOutput output = new SimpleGraphics2DExporterOutput();
|
|
output.setGraphics2D(g2d);
|
|
exporter.setExporterOutput(output);
|
|
|
|
SimpleGraphics2DReportConfiguration config = new SimpleGraphics2DReportConfiguration();
|
|
config.setPageIndex(i);
|
|
exporter.setConfiguration(config);
|
|
|
|
exporter.exportReport();
|
|
g2d.dispose();
|
|
pageImages.add(pageImage);
|
|
}
|
|
|
|
// 5. Combine pages into single tall image
|
|
int totalHeight = 0;
|
|
for (BufferedImage img : pageImages) {
|
|
totalHeight += img.getHeight();
|
|
}
|
|
|
|
BufferedImage combined = new BufferedImage(pageWidth, totalHeight, BufferedImage.TYPE_INT_RGB);
|
|
java.awt.Graphics2D g = combined.createGraphics();
|
|
g.setColor(java.awt.Color.WHITE);
|
|
g.fillRect(0, 0, pageWidth, totalHeight);
|
|
|
|
int yOffset = 0;
|
|
for (BufferedImage img : pageImages) {
|
|
g.drawImage(img, 0, yOffset, null);
|
|
yOffset += img.getHeight();
|
|
}
|
|
g.dispose();
|
|
|
|
// 6. Write PNG
|
|
ImageIO.write(combined, "png", new File(outputPath));
|
|
|
|
System.out.println("OK: " + outputPath
|
|
+ " (pages=" + pages
|
|
+ ", size=" + pageWidth + "x" + totalHeight
|
|
+ ", scale=" + scale + ")");
|
|
} catch (JRException e) {
|
|
System.err.println("JASPER_ERROR: " + e.getMessage());
|
|
e.printStackTrace();
|
|
System.exit(3);
|
|
}
|
|
}
|
|
}
|