Reputation: 3021
I have an application where i need to select a folder containing pictures and need to display a thumbnail view of those images using Java . I dont have any idea as to how to represent images in a thumbnail format .
Any resources like code examples , theory or links would be really helpful.
Thank You
Upvotes: 2
Views: 4964
Reputation: 23950
The following code scales the entire image into an area. You can copy-paste the code and run it to see what it does.
The interesting call is g2d.drawImage(img, 0, 0, thumb.getWidth() - 1, thumb.getHeight() - 1, 0, 0, img.getWidth() - 1, img.getHeight() - 1, null);
which copies the image into the thumbnail, scaling it to fit.
If you want different scalings to preserve the aspect ratio you could decide to use scale() on the g2d, or select a different source coordinates.
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ThumbnailFactory {
public ThumbnailFactory() {
}
public void run(String folder) {
File dir = new File(folder);
for (File file : dir.listFiles()) {
createThumbnail(file);
}
}
private void createThumbnail(File file) {
try {
// BufferedImage is the best (Toolkit images are less flexible)
BufferedImage img = ImageIO.read(file);
BufferedImage thumb = createEmptyThumbnail();
// BufferedImage has a Graphics2D
Graphics2D g2d = (Graphics2D) thumb.getGraphics();
g2d.drawImage(img, 0, 0,
thumb.getWidth() - 1,
thumb.getHeight() - 1,
0, 0,
img.getWidth() - 1,
img.getHeight() - 1,
null);
g2d.dispose();
ImageIO.write(thumb, "PNG", createOutputFile(file));
} catch (Exception e) {
e.printStackTrace();
}
}
private File createOutputFile(File inputFile) {
// You'll want something better than this...
return new File(inputFile.getAbsolutePath()
+ ".thumb.png");
}
private BufferedImage createEmptyThumbnail() {
return new BufferedImage(100, 200,
BufferedImage.TYPE_INT_RGB);
}
public static void main(String[] args) {
ThumbnailFactory fac = new ThumbnailFactory();
fac.run("c:\\images");
}
}
Upvotes: 1
Reputation: 11264
I have this code that I use in one of my projects. I found on the net a while ago (not sure where but if anyone recognises it please let me know so I can reference it):
private static byte[] createThumbnail(byte[] bytes)
{
try
{
double scale;
int sizeDifference, originalImageLargestDim;
Image inImage = ImageIO.read(new ByteArrayInputStream(bytes));
//find biggest dimension
if(inImage.getWidth(null) > inImage.getHeight(null))
{
scale = (double)LARGEST_DIMENSION/(double)inImage.getWidth(null);
sizeDifference = inImage.getWidth(null) - LARGEST_DIMENSION;
originalImageLargestDim = inImage.getWidth(null);
}
else
{
scale = (double)LARGEST_DIMENSION/(double)inImage.getHeight(null);
sizeDifference = inImage.getHeight(null) - LARGEST_DIMENSION;
originalImageLargestDim = inImage.getHeight(null);
}
//create an image buffer to draw to
BufferedImage outImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); //arbitrary init so code compiles
Graphics2D g2d;
AffineTransform tx;
if(scale < 1.0d) //only scale if desired size is smaller than original
{
int numSteps = sizeDifference / 100;
int stepSize = sizeDifference / numSteps;
int stepWeight = stepSize/2;
int heavierStepSize = stepSize + stepWeight;
int lighterStepSize = stepSize - stepWeight;
int currentStepSize, centerStep;
double scaledW = inImage.getWidth(null);
double scaledH = inImage.getHeight(null);
if(numSteps % 2 == 1) //if there's an odd number of steps
centerStep = (int)Math.ceil((double)numSteps / 2d); //find the center step
else
centerStep = -1; //set it to -1 so it's ignored later
Integer intermediateSize = originalImageLargestDim, previousIntermediateSize = originalImageLargestDim;
for(Integer i=0; i<numSteps; i++)
{
if(i+1 != centerStep) //if this isn't the center step
{
if(i == numSteps-1) //if this is the last step
{
//fix the stepsize to account for decimal place errors previously
currentStepSize = previousIntermediateSize - LARGEST_DIMENSION;
}
else
{
if(numSteps - i > numSteps/2) //if we're in the first half of the reductions
currentStepSize = heavierStepSize;
else
currentStepSize = lighterStepSize;
}
}
else //center step, use natural step size
{
currentStepSize = stepSize;
}
intermediateSize = previousIntermediateSize - currentStepSize;
scale = (double)intermediateSize/(double)previousIntermediateSize;
scaledW = (int)scaledW*scale;
scaledH = (int)scaledH*scale;
outImage = new BufferedImage((int)scaledW, (int)scaledH, BufferedImage.TYPE_INT_RGB);
g2d = outImage.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, outImage.getWidth(), outImage.getHeight());
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
tx = new AffineTransform();
tx.scale(scale, scale);
g2d.drawImage(inImage, tx, null);
g2d.dispose();
inImage = new ImageIcon(outImage).getImage();
previousIntermediateSize = intermediateSize;
}
}
else
{
//just copy the original
outImage = new BufferedImage(inImage.getWidth(null), inImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
g2d = outImage.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, outImage.getWidth(), outImage.getHeight());
tx = new AffineTransform();
tx.setToIdentity(); //use identity matrix so image is copied exactly
g2d.drawImage(inImage, tx, null);
g2d.dispose();
}
//JPEG-encode the image and write to file.
ByteArrayOutputStream os = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
encoder.encode(outImage);
return os.toByteArray();
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
Upvotes: 1