Wie kann man ein Bild rasterartig zerlegen und in einem GridLayout platzieren?

Die Klasse java.awt.image.BufferedImage ermöglicht es, ein BufferedImage-Objekt in Bruchstücke zu zerlegen. Diese können anschließend beliebig auf einer Komponente angeordnet werden.

Das Auslesen des vorhandenen Bildes geschieht folgendermaßen:
Die statische Methode read() der Klasse ImageIO liefert durch Auslesen des File-Objektes des Dateipfades ein BufferedImage. Um Fehler beim Lesen abzufangen, muss dies innerhalb eines try-catch-Blockes erfolgen.
Das Rastern des Bildes erfolgt auf der Basis einer Variablen anz, die einerseits die Größe der gerasterten Fläche selbst und andererseits die Aufteilung des Bildes bestimmt: Sie legt die Anzahl der JLabel und die quadratische Gestaltung des GridLayouts des aufnehmenden Containers, hier ein JPanel, fest.
Das Zerlegen des BufferedImages erfolgt durch die Methode BufferedImage.getSubimage(). Sie erwartet vier Parameter: die x- und y-Koordinaten der linken oberen Ecke des jeweiligen Teilstückes, sowie dessen Breite und Höhe. Die Zerlegung selbst erfolgt in einer doppelten Schleife, in der zunächst die Reihen und anschließend innerhalb dieser die einzelnen Zellen definiert werden. Die Methode gibt ein Image-Objekt zurück, das in ein ImageIcon konvertiert wird. Das kann schließlich einem darstellenden JLabel übergeben werden. Die JLabel selber werden im Konstruktor dem zentralen Container gemäß dessen GridLayout der Reihe nach zugeteilt.

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class BildRastern extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel panel;
    private JLabel[] labels;
    private ImageIcon icon;
    private String imgPath = "test.jpg";
    private int anz = 4;
    
    public BildRastern(){
        
        panel = new JPanel();
        panel.setLayout(new GridLayout(anz, anz, 2, 2));
        labels = new JLabel[anz * anz];
        for (int i=0; i<labels.length; i++){
            labels[i] = new JLabel();
            panel.add(labels[i], BorderLayout.CENTER);
        }
        
        this.add(panel, BorderLayout.CENTER);
        this.setSize(600, 600);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        // Bild erst nach der Definition der Größe importieren
        setImage();
        this.setVisible(true);
    }
    
    private BufferedImage loadImage(){
        File imgFile = new File(imgPath);
        BufferedImage buff = null;
        try {
            buff = ImageIO.read(imgFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buff;
    }
    
    private void setImage(){
        BufferedImage bi = loadImage();
        Image newImg;
        int div = (int) Math.sqrt(labels.length);
        for(int i=0; i<div; i++){
            for(int j=0; j<div; j++){
                newImg = bi.getSubimage(j*(this.getWidth()/div), i*(this.getHeight()/div), this.getWidth()/div, this.getHeight()/div);
                icon = new ImageIcon(newImg);
                System.out.println(i*j);
                labels[(i*div+j)].setIcon(icon);
            }
        }
    }

    public static void main(String[] args) {
        new BildRastern();
    }
}