Quote Originariamente inviata da NonnoFausto Visualizza il messaggio
img = img.getScaledInstance(pixels, -1, -1);
Il 3° parametro è il "hints". -1 non mi pare uno dei valori validi. Vedi documentazione.

Quote Originariamente inviata da NonnoFausto Visualizza il messaggio
BufferedImage bimage = new BufferedImage(pixels, pixels, BufferedImage.TYPE_INT_ARGB);
L'immagine originale è quadrata? Per sicurezza, prendi width/height della immagine SCALATA.

Quote Originariamente inviata da NonnoFausto Visualizza il messaggio
bimage.getGraphics().drawImage(img, 0, 0, null);
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(img, 0, 0, null);
bGr.dispose();
bimage.getGraphics().drawString(stringa, pixels/2, pixels/2);
Perché usi più volte getGraphics()/createGraphics() ??
Usane solo uno (il createGraphics perché dà già un Graphics2D), tieni il Graphics2D in UNA variabile. Usala per disegnare. E alla fine dei disegni fai dispose(). Punto.

C'è una questione un po' "subdola". Il Toolkit carica le immagini in modo asincrono. Vuol dire che anche se la immagine fosse molto grande, il getImage ritorna quasi subito e poi il caricamento avviene in seguito in modo appunto asincrono.
Problema: quando fai il drawImage non è certo che la immagine sia completa. Dovresti usare un MediaTracker per attendere il completamento del caricamento.

P.S. nel drawString il x/y NON è il centro perfetto della stringa. Invece è il punto del "baseline" al primo carattere.