Tu masz przykład skalowania i zapisywania w pętli kolejnych wersji obrazków. Komentarze powinny pomóc w samodzielnym zrobieniu metody kopiującej.
private Image2D getImg()
{
BufferedImage result = !isTargetDimension() && highQuality?
smooth() : buf; //przygotowanie obrazka
while(!isTargetDimension())
{ //dwukrotne zmniejszenie wymiarów w przypadku downscalingu
if(newWidth < w && (w >>>= 1) < newWidth)
w = newWidth;
if(newHeight < h && (h >>>= 1) < newHeight)
h = newHeight;
//nowy pusty obraz
final BufferedImage work = new BufferedImage(w, h, type);
//bez zbędnej kopii obrazka w pamięci GPU
work.setAccelerationPriority(NO_ACCELERATION);
//przygotowanie kopii do przerysowania
final Graphics2D g2 = work.createGraphics();
//interpolacja - całkowicie zbędna w przypadku kopii 1:1
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation);
//wyrenderowanie kopii
g2.drawImage(result, 0, 0, w, h, null); //result->work
g2.dispose();
result = work; //przepisanie kolejnej wersji
}
return new Image2D(result);
}
Dość istotne jest wyłączenie akceleracji obrazków buforowanych. Java domyślnie każdy utworzony obrazek duplikuje w miarę możliwości do pamięci układu graficznego. Robi to w formacie zgodnym z bieżącym planem graficznym - niekoniecznie zgodnym z tym w pamięci Javy, a więc potencjalnie dodatkowo spowolnionym. Normalnie dla obrazków docelowych jest to korzystne bo w przypadku potrzeby wyświetlenia staje się to błyskawicznie. Jednak przy intensywnych operacjach na obrazach w pamięci Javy jest to tylko zbędne i bardzo czasochłonne uszczęśliwianie na siłę.