BufferedImage und Graphics2D sind deine Freunde um das umzusetzen. Und ich würde auch behaupten, viel Zeit dürfte das nicht benötigen.
Wenn du die Bilder in einem Raster anordnest, und die Bilder haben unterschiedliche Längen und Seitenverhältnisse, dann bleibt dir nichts anderes übrig als die Bilder in ihrem Seitenverhältnis zu skalieren. Das ist relativ einfach
double scaledWidth = something;
double scaledHeight = h * newWidth / w;
wenn du also eine maximale Seitenlänge hast
double maxWidth = something;
double maxHeight = something;
double maxWidthWidthRatio = maxWidth / imageWidth;
double maxHeightHeightRatio = maxHeight / imageHeight;
if( maxWidthWidthRatio > maxHeightHeightRatio ) {
newImageWidth = maxWidth;
newImageHeight = h * maxWidthWidthRatio;
} else {
newImageWidth = w * maxHeightHeightRatio;
newImageHeight = maxHeight;
}
Dann haben die aber halt Lücken untereinander. Wenn du jetzt versuchst den Platz möglichst effektiv mit unterschiedlich großen Bildern zu füllen, dann haben wir ein Problem. Denn dafür gibt es keine mathematische Lösung.