Rev 1074 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package ak.photoalbum.images.jiu;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.awt.image.ImageObserver;
import org.apache.log4j.Logger;
import ak.photoalbum.images.ImageResizer;
import net.sourceforge.jiu.data.BilevelImage;
import net.sourceforge.jiu.data.Gray8Image;
import net.sourceforge.jiu.data.MemoryRGB24Image;
import net.sourceforge.jiu.data.Paletted8Image;
import net.sourceforge.jiu.data.PixelImage;
import net.sourceforge.jiu.data.RGB24Image;
import net.sourceforge.jiu.data.RGBIndex;
import net.sourceforge.jiu.geometry.Resample;
public class JiuResizer
implements ImageResizer
{
protected static final int DEFAULT_ALPHA = 0xff000000;
protected static final int FILTER_TYPE = Resample.FILTER_TYPE_HERMITE;
/*
Possible type small, ms medium, ms quality
-----------------------------------------------------------
FILTER_TYPE_BOX 2.4 3.5 very bad
FILTER_TYPE_TRIANGLE 2.9 5.2
FILTER_TYPE_B_SPLINE 3.6 7.2
FILTER_TYPE_BELL 3.5 6.1
FILTER_TYPE_HERMITE 2.9 5.3
FILTER_TYPE_LANCZOS3 4.7 9.7 the best
FILTER_TYPE_MITCHELL 3.6 7.1
*/
private static final Logger logger = Logger.getLogger(JiuResizer.class);
public JiuResizer()
{
}
public BufferedImage resize(Image origin, int newWidth, int newHeight)
{
long timeStart = System.currentTimeMillis();
try {
RGB24Image image = convertImageToRGB24Image(origin);
Resample resample;
if(image == null) return null;
if(image.getWidth() == newWidth && image.getHeight() == newHeight)
return convertToAwtImage(image, DEFAULT_ALPHA);
resample = new Resample();
resample.setInputImage(image);
resample.setSize(newWidth, newHeight);
resample.setFilter(FILTER_TYPE);
resample.process();
return convertToAwtImage(resample.getOutputImage(), DEFAULT_ALPHA);
}
catch(Exception ex) {
logger.warn("Cannot resize image", ex);
throw new RuntimeException(ex.getMessage());
}
finally {
if(logger.isDebugEnabled()) {
logger.debug("resized in " + (System.currentTimeMillis() - timeStart) + " ms");
}
}
}
protected static BufferedImage convertToAwtImage(PixelImage image, int alpha)
{
if (image == null)
{
return null;
}
if (image instanceof RGB24Image)
{
return convertToAwtImage((RGB24Image)image, alpha);
}
else
if (image instanceof Gray8Image)
{
return null; //convertToAwtImage((Gray8Image)image, alpha);
}
else
if (image instanceof Paletted8Image)
{
return null; //convertToAwtImage((Paletted8Image)image, alpha);
}
else
if (image instanceof BilevelImage)
{
return null; //convertToAwtImage((BilevelImage)image, alpha);
}
else
{
return null;
}
}
protected static BufferedImage convertToAwtImage(RGB24Image image, int alpha)
{
if (image == null)
{
return null;
}
int width = image.getWidth();
int height = image.getHeight();
if (width < 1 || height < 1)
{
return null;
}
int[] pixels = new int[width];
byte[] red = new byte[width];
byte[] green = new byte[width];
byte[] blue = new byte[width];
BufferedImage newImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < height; y++)
{
image.getByteSamples(RGBIndex.INDEX_RED, 0, y, width, 1, red, 0);
image.getByteSamples(RGBIndex.INDEX_GREEN, 0, y, width, 1, green, 0);
image.getByteSamples(RGBIndex.INDEX_BLUE, 0, y, width, 1, blue, 0);
convertFromRGB24(red, 0, green, 0, blue, 0, alpha, pixels, 0, width);
for(int x = 0; x < width; x++)
newImage.setRGB(x, y, pixels[x]);
}
return newImage;
}
protected static void convertFromRGB24(
byte[] srcRed, int srcRedOffset,
byte[] srcGreen, int srcGreenOffset,
byte[] srcBlue, int srcBlueOffset,
int alpha,
int[] dest, int destOffset,
int num)
{
while (num-- > 0)
{
dest[destOffset++] =
alpha |
(srcBlue[srcBlueOffset++] & 0xff) |
((srcGreen[srcGreenOffset++] & 0xff) << 8) |
((srcRed[srcRedOffset++] & 0xff) << 16);
}
}
/**
* Creates an {@link RGB24Image} from the argument AWT image instance.
* @param image AWT image object to be converted to a {@link RGB24Image}
* @return a {@link RGB24Image} object holding the
* image data from the argument image
*/
protected static RGB24Image convertImageToRGB24Image(Image image)
{
if (image == null)
{
return null;
}
int width = image.getWidth(null);
int height = image.getHeight(null);
if (width < 1 || height < 1)
{
return null;
}
int[] pixels = new int[width * height];
PixelGrabber pg = new PixelGrabber(
image, 0, 0, width, height, pixels, 0, width);
try
{
pg.grabPixels();
}
catch (InterruptedException e)
{
return null;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0)
{
//System.err.println("image fetch aborted or errored");
return null;
}
RGB24Image result = new MemoryRGB24Image(width, height);
int offset = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
int pixel = pixels[offset++] & 0xffffff;
result.putSample(RGBIndex.INDEX_RED, x, y, pixel >> 16);
result.putSample(RGBIndex.INDEX_GREEN, x, y, (pixel >> 8) & 0xff);
result.putSample(RGBIndex.INDEX_BLUE, x, y, pixel & 0xff);
}
}
return result;
}
}