Ja som si svojho casu urobil nieco taketo, ked som potreboval zapisovat
thumbnaily obrazkov do PDF suboru (uznavam, ze kod nieje nijako
optimalizovany, ba je priam prasacky ;-) ):
...
import java.io.*;
import javax.imageio.*;
import java.awt.image.*;
import java.awt.geom.*;
...
...
private Image getImage(InputStream is, int maxWidth, int maxHeight, String
formatName) {
Image image = null;
int width = 0;
int height = 0;
if (is != null && formatName != null) {
try {
BufferedImage bi = ImageIO.read(is);
if (bi != null && (width = bi.getWidth()) > 0 &&
(height = bi.getHeight()) > 0) {
float ratio = 1;
float ratioW = (float)maxWidth / (float)width;
float ratioH = (float)maxHeight / (float)height;
ratio = (ratioW > 0 && ratioW <= ratioH ?
ratioW : ratio);
ratio = (ratioH > 0 && ratioH <= ratioW ?
ratioH : ratio);
if (ratio != 1) {
AffineTransformOp op = new
AffineTransformOp(
AffineTransform.getScaleInstance(ratio, ratio),
//AffineTransformOp.TYPE_BILINEAR
AffineTransformOp.TYPE_NEAREST_NEIGHBOR
);
bi = op.filter(bi, null);
}
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
ImageIO.write(bi, formatName, baos);
bi = null;
try {
image =
Image.getInstance(baos.toByteArray());
} catch (BadElementException _beEx) {
System.err.println(_beEx.getMessage());
image = null;
}
if (baos != null) {
baos.flush();
baos.close();
baos = null;
}
}
} catch (IOException _ioEx) {
System.err.println(_ioEx.getMessage());
image = null;
}
}
return image;
}
...
...
formatName je String, ktory urcuje ci to bude JPEG, PNG alebo nieco ine, takze
formatName je tvaru: "JPEG" alebo "PNG" alebo iny graficky format (vid ImageIO
API).
Pre thumbnail sa uvedie len maximalna povolena vyska a maximalna povolena sirka
a vypocita si to ratio podla ktoreho to bude resizovat, aby platila bud
maximalna povolena vyska alebo sirka (uz si to strazi samo, aby sedel pomer
stran). Ratio = 1 znamena, ze k resizovaniu nedochadza.
Vstupny stream je mozne citat bud zo suboru alebo z databazy, ...
AffineTransformOp je potrebne si vyskusat, mne osobne sa zdalo lepsie resize
pomocou TYPE_NEAREST_NEIGHBOR pred TYPE_BILINEAR.
Cele pouzitie je napr. takto (konkretne pri tom mojom zapise thumbnailu do PDF
- com.lowagie):
...
...
Image img = getImage(result.getBinaryStream("fileData"), 116, 119, "PNG");
if (img != null) {
img.setAlignment(Image.RIGHT | Image.TEXTWRAP);
document.add(img);
}
...
...
V tomto pripade metoda getImage vracia objekt typu Image, ale je mozne ju
prepisat bez problemov na zapis priamo do vystupneho streamu, nieco na styl:
...
...
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, formatName, baos);
bi = null;
response.setContentType(contentType);
response.setContentLength(baos.size());
baos.writeTo(response.getOutputStream());
if (baos != null) {
baos.flush();
baos.close();
baos = null;
}
...
...
kde je potrebne vsak nastavit este contentType, ak to posielate priamo do
browsra.
ImageIO.write(..) vie zapisovat aj priamo do OutputStream, ale v oboch
pripadoch som potreboval ByteArrayOutputStream. V prvom pripade aby som dokazal
vytvorit Image a v druhom aby som dokazal nastavit Content-Length pre vystup do
browsra.
Vravim, nie je to ziadna optimalizovana vec, urcite je to aj trosku prasacky
napisane, ale nechcelo sa mi to tu teraz narychlo nejako opravovat :-)
Ak ma niekto nieco lepsie, rad uvitam aj ja nove napady alebo upravy tohto
mojho bordelu ;-)
TimeLord