I have snippet of code that I am using for the purpose of resizing an image to a curtain size (I want to change the resolution to something like 200 dpi). Basically the reason I need it is because I want to display the image that the user have picked (somewhat large) and then if the user approves I want to display the same image in a different place but using a smaller resolution. Unfortunately, if I give it a large image nothing appears on the screen. Also, if I change
imageLabel.setIcon(newIcon);
to
imageLabel.setIcon(icon);
I get the image to display but not in the correct resolution that's how I know that I have a problem inside this snipper of code and not somewhere else.
Image img = icon.getImage();
BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
BufferedImage bi = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
boolean myBool = g.drawImage(img, 0, 0, 100, 100, null);
System.out.println(myBool);
ImageIcon newIcon = new ImageIcon(bi);
imageLabel.setIcon(newIcon);
submitText.setText(currentImagePath);
imageThirdPanel.add(imageLabel);
You don't really have to care about the details of scaling images. The Image class has already a method getScaledInstance(int width, int height, int hints) designed for this purpose.
Java documentation says:
Creates a scaled version of this image. A new Image object is returned
which will render the image at the specified width and height by
default. The new Image object may be loaded asynchronously even if the
original source image has already been loaded completely. If either
the width or height is a negative number then a value is substituted
to maintain the aspect ratio of the original image dimensions.
And you can use it like this:
// Scale Down the original image fast
Image scaledImage = imageToScale.getScaledInstance(newWidth, newHighth, Image.SCALE_FAST);
// Repaint this component
repaint();
Check this for a complete example.
Here is my solution:
private BufferedImage resizeImage(BufferedImage originalImage, int width, int height, int type) throws IOException {
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
Try this CODE to resize image :
public static Image scaleImage(Image original, int newWidth, int newHeight) {
//do nothing if new and old resolutions are same
if (original.getWidth() == newWidth && original.getHeight() == newHeight) {
return original;
}
int[] rawInput = new int[original.getHeight() * original.getWidth()];
original.getRGB(rawInput, 0, original.getWidth(), 0, 0, original.getWidth(), original.getHeight());
int[] rawOutput = new int[newWidth * newHeight];
// YD compensates for the x loop by subtracting the width back out
int YD = (original.getHeight() / newHeight) * original.getWidth() - original.getWidth();
int YR = original.getHeight() % newHeight;
int XD = original.getWidth() / newWidth;
int XR = original.getWidth() % newWidth;
int outOffset = 0;
int inOffset = 0;
for (int y = newHeight, YE = 0; y > 0; y--) {
for (int x = newWidth, XE = 0; x > 0; x--) {
rawOutput[outOffset++] = rawInput[inOffset];
inOffset += XD;
XE += XR;
if (XE >= newWidth) {
XE -= newWidth;
inOffset++;
}
}
inOffset += YD;
YE += YR;
if (YE >= newHeight) {
YE -= newHeight;
inOffset += original.getWidth();
}
}
return Image.createRGBImage(rawOutput, newWidth, newHeight, false);
}
Another example is given here :
2D-Graphics/LoadImageandscaleit.htm">http://www.java2s.com/Tutorial/Java/0261_2D-Graphics/LoadImageandscaleit.htm
http://www.java2s.com/Code/JavaAPI/java.awt/ImagegetScaledInstanceintwidthintheightinthints.htm
i want to rotate an image and in next level i want to resize it plese
help me.
i create a class that extended from JPanel and override paintComponent() method
for drawing image.
public class NewJPanel extends javax.swing.JPanel {
/** Creates new form NewJPanel */
public NewJPanel() {
initComponents();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 20, 20, this);
}
Here is some code I use. You can modify it to fit your needs.
Resize Image:
/**
* Resizes the image
*
* #param filePath File path to the image to resize
* #param w Width of the image
* #param h Height of the image
* #return A resized image
*/
public ImageIcon resizeImage(String filePath, int w, int h) {
String data = filePath;
BufferedImage bsrc, bdest;
ImageIcon theIcon;
//scale the image
try {
if (dataSource == DataTypeEnum.file) {
bsrc = ImageIO.read(new File(data));
} else {
bsrc = ImageIO.read(new URL(filePath));
}
bdest = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = bdest.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(
(double) w / bsrc.getWidth(), (double) h / bsrc.getHeight());
g.drawRenderedImage(bsrc, at);
//add the scaled image
theIcon = new ImageIcon(bdest);
return theIcon;
} catch (Exception e) {
Window.getLogger().warning("This image can not be resized. " +
"Please check the path and type of file.");
//restore the old background
return null;
}
}
Rotate Image:
NOTE: The angle is in radians
public static BufferedImage rotate(BufferedImage image, double angle) {
double sin = Math.abs(Math.sin(angle)),
cos = Math.abs(Math.cos(angle));
int w = image.getWidth(),
h = image.getHeight();
int neww = (int) Math.floor(w * cos + h * sin),
newh = (int) Math.floor(h * cos + w * sin);
GraphicsConfiguration gc = getDefaultConfiguration();
BufferedImage result =
gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
Graphics2D g = result.createGraphics();
g.translate((neww - w) / 2, (newh - h) / 2);
g.rotate(angle, w / 2, h / 2);
g.drawRenderedImage(image, null);
g.dispose();
return result;
}
Without giving away a full solution
Graphics2D has rotate and scale functions.
Use the BufferedImage class
BufferedImage newImg = new BufferedImage(newWidth, newHeight, imageType);
newImg.createGraphics().drawImage(oldImg,0,0,newWidth, newHeight,0,0,oldWidth,oldHeight, null);
then just repaint using newImg instead of the old image, should work, I'm not near a compiler at the moment to test.
http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Graphics.html#drawImage%28java.awt.Image,%20int,%20int,%20int,%20int,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver%29
I need to perform java image crop and resize without an X server.
I tried several methods.
the first method below works, but outputs a fairly ugly resized image (probably using nearest neighbor algorithm for the resize:
static BufferedImage createResizedCopy(Image originalImage, int scaledWidth, int scaledHeight, boolean preserveAlpha)
{
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha)
{
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
So I decided to use bicubic resize, which gives better results:
public static BufferedImage createResizedCopy(BufferedImage source, int destWidth, int destHeight, Object interpolation)
{
if (source == null) throw new NullPointerException("source image is NULL!");
if (destWidth <= 0 && destHeight <= 0) throw new IllegalArgumentException("destination width & height are both <=0!");
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
double xScale = ((double) destWidth) / (double) sourceWidth;
double yScale = ((double) destHeight) / (double) sourceHeight;
if (destWidth <= 0)
{
xScale = yScale;
destWidth = (int) Math.rint(xScale * sourceWidth);
}
if (destHeight <= 0)
{
yScale = xScale;
destHeight = (int) Math.rint(yScale * sourceHeight);
}
GraphicsConfiguration gc = getDefaultConfiguration();
BufferedImage result = gc.createCompatibleImage(destWidth, destHeight, source.getColorModel().getTransparency());
Graphics2D g2d = null;
try
{
g2d = result.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation);
AffineTransform at = AffineTransform.getScaleInstance(xScale, yScale);
g2d.drawRenderedImage(source, at);
}
finally
{
if (g2d != null) g2d.dispose();
}
return result;
}
public static GraphicsConfiguration getDefaultConfiguration()
{
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
return gd.getDefaultConfiguration();
}
This worked fine until I tried to put it on the server, and at this point I bumped into java.awt.HeadlessException.
my attempts to play with java.awt.headless=true failed.
So, here is the question:
How do I resize and crop and image in Java without an X server, using a bicubic interpolation algorithm?
Answer:
Using the code from Bozho comment, I created this function which does the trick (interpolation should be RenderingHints.VALUE_INTERPOLATION_*).
public static BufferedImage createResizedCopy(BufferedImage source, int destWidth, int destHeight, Object interpolation)
{
BufferedImage bicubic = new BufferedImage(destWidth, destHeight, source.getType());
Graphics2D bg = bicubic.createGraphics();
bg.setRenderingHint(RenderingHints.KEY_INTERPOLATION, interpolation);
float sx = (float)destWidth / source.getWidth();
float sy = (float)destHeight / source.getHeight();
bg.scale(sx, sy);
bg.drawImage(source, 0, 0, null);
bg.dispose();
return bicubic;
}
Check this code. Also check if Image.getScaledInstance(..) (with "smooth" scaling) doesn't solve the problem. And finally, take a look at the java-image-scaling-library.
Can someone please help with some code for creating a thumbnail for a JPEG in Java.
I'm new at this, so a step by step explanation would be appreciated.
Image img = ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH);
This will create a 100x100 pixels thumbnail as an Image object. If you want to write it back to disk simply convert the code to this:
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(ImageIO.read(new File("test.jpg")).getScaledInstance(100, 100, Image.SCALE_SMOOTH),0,0,null);
ImageIO.write(img, "jpg", new File("test_thumb.jpg"));
Also if you are concerned about speed issues (the method described above is rather slow if you want to scale many images) use these methods and the following declaration :
private BufferedImage scale(BufferedImage source,double ratio) {
int w = (int) (source.getWidth() * ratio);
int h = (int) (source.getHeight() * ratio);
BufferedImage bi = getCompatibleImage(w, h);
Graphics2D g2d = bi.createGraphics();
double xScale = (double) w / source.getWidth();
double yScale = (double) h / source.getHeight();
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
g2d.drawRenderedImage(source, at);
g2d.dispose();
return bi;
}
private BufferedImage getCompatibleImage(int w, int h) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
return image;
}
And then call :
BufferedImage scaled = scale(img,0.5);
where 0.5 is the scale ratio and img is a BufferedImage containing the normal-sized image.
As you might have found out "easy" and "good looking result" are two very different things. I have encapsulated both of these requirements into a very simple java image scaling library (Apache 2 license) that just does everything right for you.
Example code to create a thumbnail looks like this:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 150);
Your image proportions are honored, the library makes a best-guess at the method it should use based on the amount of change in the image due to scaling (FASTEST, BALANCED or QUALITY) and the best supported Java2D image types are always used to do the scaling to avoid the issue of "black" results or really terrible looking output (e.g. overly dithered GIF images).
Also, if you want to force it to output the best looking thumbnail possible in Java, the API call would look like this:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
Not only will the library use the Java2D recommended incremental scaling for you to give you the best looking result, it will also apply an optional antialiasing effect to the thumbnail (ConvolveOp with a very fine-tuned kernel) to every-so-slightly soften the transitions between pixel values so make the thumbnail look more uniform and not sharp or poppy as you might have seen when you go from very large images down to very small ones.
You can read through all the comments in the library (the code itself is doc'ed heavily) to see all the different JDK bugs that are worked around or optimizations that are made to improve the performance or memory usage. I spent a LOT of time tuning this implementation and have had a lot of good feedback from folks deploying it in web apps and other Java projects.
This is simple way of creating a 100 X 100 thumbnail without any stretch or skew in image.
private void saveScaledImage(String filePath,String outputFile){
try {
BufferedImage sourceImage = ImageIO.read(new File(filePath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
if(width>height){
float extraSize= height-100;
float percentHight = (extraSize/height)*100;
float percentWidth = width - ((width/100)*percentHight);
BufferedImage img = new BufferedImage((int)percentWidth, 100, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance((int)percentWidth, 100, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage((int)((percentWidth-100)/2), 0, 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}else{
float extraSize= width-100;
float percentWidth = (extraSize/width)*100;
float percentHight = height - ((height/100)*percentWidth);
BufferedImage img = new BufferedImage(100, (int)percentHight, BufferedImage.TYPE_INT_RGB);
Image scaledImage = sourceImage.getScaledInstance(100,(int)percentHight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
BufferedImage img2 = new BufferedImage(100, 100 ,BufferedImage.TYPE_INT_RGB);
img2 = img.getSubimage(0, (int)((percentHight-100)/2), 100, 100);
ImageIO.write(img2, "jpg", new File(outputFile));
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The JMagick library (and implementation of ImageMagick in Java) will have what you need.
the Java code above (with the scale / getCompatibleImage methods) worked great for me, but when I deployed to a server, it stopped working, because the server had no display associated with it -- anyone else with this problem can fix it by using:
BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
instead of
BufferedImage bi = getCompatibleImage(w, h);
and deleting the getCompatibleImage method
(later note -- it turns out this works great for most images, but I got a bunch from my companys marketing department that are 32 bit color depth jpeg images, and the library throws an unsupported image format exception for all of those :( -- imagemagick / jmagick are starting to look more appealing)
I have writtena util class with static methods years ago using JAI. Java Advanced Imaging API is the most reliable API in Java to deal with images. It's vector interpolation is closest thing to Photoshop in Java world. Here is one of them:
public static ByteArrayOutputStream resize(InputStream inputStream , int IMG_WIDTH,
int IMG_HEIGHT) throws Exception {
BufferedImage originalImage = ImageIO.read(inputStream);
int type = originalImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB
: originalImage.getType();
BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
type);
{
Graphics2D g = resizedImage.createGraphics();
g.drawImage(originalImage, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
g.dispose();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(resizedImage, "png", bos);
return bos;
}
I know this is a pretty old post. I have been looking for a solution to generate the thumbnail so end up using this
Thumbnails.of(originalImage).scale(0.25).asBufferedImage();
if you are using for mobile would suggest to set the scale to 0.45
Thumbnails.of(originalImage).scale(0.45).asBufferedImage();
https://github.com/coobird/thumbnailator
This is certainly much faster using the Graphics2D as have tested the both options.
I've used Thumbnailator! It solved my problem with two lines of code.
https://github.com/coobird/thumbnailator
Simple way to create a thumbnail without stretching or a library. Works with transparency in pngs, too.
public File createThumbnail(String imageUrl, String targetPath) {
final int imageSize = 100;
File thumbnail = new File(targetPath);
try {
thumbnail.getParentFile().mkdirs();
thumbnail.createNewFile();
BufferedImage sourceImage = ImageIO.read(new File(imageUrl));
float width = sourceImage.getWidth();
float height = sourceImage.getHeight();
BufferedImage img2;
if (width > height) {
float scaledWidth = (width / height) * (float) imageSize;
float scaledHeight = imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledWidth - scaledHeight) / 2f);
img2 = img.getSubimage(offset, 0, imageSize, imageSize);
}
else if (width < height) {
float scaledWidth = imageSize;
float scaledHeight = (height / width) * (float) imageSize;
BufferedImage img = new BufferedImage((int) scaledWidth, (int) scaledHeight, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance((int) scaledWidth, (int) scaledHeight, Image.SCALE_SMOOTH);
img.createGraphics().drawImage(scaledImage, 0, 0, null);
int offset = (int) ((scaledHeight - scaledWidth) / 2f);
img2 = img.getSubimage(0, offset, imageSize, imageSize);
}
else {
img2 = new BufferedImage(imageSize, imageSize, sourceImage.getType());
Image scaledImage = sourceImage.getScaledInstance(imageSize, imageSize, Image.SCALE_SMOOTH);
img2.createGraphics().drawImage(scaledImage, 0, 0, null);
}
ImageIO.write(img2, "png", thumbnail);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return thumbnail;
}
I have created a application called fotovault (sourceforge.net) which can upload images and create thumbnails in java using imagej apis.
Please read my blog below
http://www.gingercart.com/Home/java-snippets/create-image-thumbnail-in-java-using-imagej-api
I have gone through a blog according to which you have following options -
For simple RGB files use ImageScalr . ImageIO class is used for reading files and ImageScalr to create thumbnails
For supporting RGB + CYMK, use ImageIO and JAI (Java Advanced Imaging) API for reading files and ImageScalr to create thumbnail.
In case you don’t know what file formats, color mode you are going to deal with, safest option is to use ImageMagick.
Here is link that gives a complete answer with code snippets.
There are many image processing frameworks available that you can do this with just a few lines. The example below generates the thumbnails in different resolutions (given a width as reference) using Marvin Framework. The three thumbnails were generated in 92 ms.
input:
output:
import static marvin.MarvinPluginCollection.*;
MarvinImage image = MarvinImageIO.loadImage("./res/input.jpg");
MarvinImage scaledImage = new MarvinImage(1,1);
scale(image, scaledImage, 250);
MarvinImageIO.saveImage(scaledImage, "./res/output_x250.jpg");
scale(image, scaledImage, 150);
MarvinImageIO.saveImage(scaledImage, "./res/output_x150.jpg");
scale(image, scaledImage, 50);
MarvinImageIO.saveImage(scaledImage, "./res/output_x50.jpg");
Maybe the simplest approach would be:
static public BufferedImage scaleImage(BufferedImage image, int max_width, int max_height) {
int img_width = image.getWidth();
int img_height = image.getHeight();
float horizontal_ratio = 1;
float vertical_ratio = 1;
if(img_height > max_height) {
vertical_ratio = (float)max_height / (float)img_height;
}
if(img_width > max_width) {
horizontal_ratio = (float)max_width / (float)img_width;
}
float scale_ratio = 1;
if (vertical_ratio < horizontal_ratio) {
scale_ratio = vertical_ratio;
}
else if (horizontal_ratio < vertical_ratio) {
scale_ratio = horizontal_ratio;
}
int dest_width = (int) (img_width * scale_ratio);
int dest_height = (int) (img_height * scale_ratio);
BufferedImage scaled = new BufferedImage(dest_width, dest_height, image.getType());
Graphics graphics = scaled.getGraphics();
graphics.drawImage(image, 0, 0, dest_width, dest_height, null);
graphics.dispose();
return scaled;
}
Solution for the case when you want to create a quadrate (75x75) thumbnail from the non-quadrate source.
Code below first crop original image to quadrate using smaller size than resizes the quadrate image.
public static void generateThumbnailWithCrop(String imgPath, String thumbnailPath, int size) throws IOException {
BufferedImage sourceImage = ImageIO.read(new File(imgPath));
int width = sourceImage.getWidth();
int height = sourceImage.getHeight();
int smallerSize = width > height ? height : width;
BufferedImage quadrateImage = cropToQuadrate(sourceImage, smallerSize);
int type = quadrateImage.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : quadrateImage.getType();
BufferedImage resizedImage = resizeImageWithHint(quadrateImage, type, size, size);
File thumb = new File(thumbnailPath);
thumb.getParentFile().mkdirs();
ImageIO.write(resizedImage, "jpg", thumb);
}
private static BufferedImage cropToQuadrate(BufferedImage sourceImage, int size) {
BufferedImage img = sourceImage.getSubimage(0, 0, size, size);
BufferedImage copyOfImage = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = copyOfImage.createGraphics();
g.drawImage(img, 0, 0, null);
return copyOfImage;
}
private static BufferedImage resizeImageWithHint(BufferedImage originalImage, int type, int width, int height) {
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setComposite(AlphaComposite.Src);
g.drawImage(originalImage, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
Thumbnails4j (I'm a maintainer, but it's owned by Elastic) is a java library that can be used to create thumbnails from image files, as well as from other file types.
File input = new File("/path/to/my_file.jpeg");
Thumbnailer thumbnailer = new ImageThumbnailer("png"); // or "jpg", whichever output format you want
List<Dimensions> outputDimensions = Collections.singletonList(new Dimensions(100, 100));
BufferedImage output = thumbnailer.getThumbnails(input, outputDimensions).get(0);