There is a logo image displayed on Login screen inside JPanel. This image looks blurry on large monitor screens. Can anybody tell me how to fix the issue of blurred images, so that images looks sharp and clear on large monitor screens ?
Do I have to make high resolution images and scale down according to screen size ?
Below is the method to resize images in proportion.
public ImagePanel(String url, int w, int h) {
try {
InputStream is = getFileFromResourceAsStream(url);
image = ImageIO.read(is);
imageurl = url;
width=w;
height=h;
isscaled = true;
outputImage = new BufferedImage(w,h, image.getType());
} catch (IOException ex) {
ex.printStackTrace();
}
}
Here how to calculate the new height and width to be passed as parameter according to screen size ?
Thank you.
I'm using JVM 14.0.2 in VSCode IDE.
The purpose of the code is to change the original input image to grayscale image and save the new gray image to the desired location.
The code runs with no exceptions and i tried to print some progress lines(System.out.println("Saving completed...");), those lines printed throughout the program where i plugged in. However, when i go to the selected filepath to search for the saved GrayScale image, i do not see the new image in the directory.
I then tried the BlueJ IDE, and the gray image was saved. Can you check if it's VSCode developing environment issue or my code issue? or I need a different class/method to edit images in VSCode? Thanks for your help.Let me know if you need more details.
public class GrayImage {
public static void main(String args[]) throws IOException {
BufferedImage img = null;
// read image
try {
File f = new File("C:\\original.jpg");
img = ImageIO.read(f);
// get image width and height
int width = img.getWidth();
int height = img.getHeight();
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// convert to grayscale
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color color = new Color(img.getRGB(x, y));
int r = (int) color.getRed();
int g = (int) color.getBlue();
int b = (int) color.getGreen();
// calculate average
int avg = (r + g + b) / 3;
// replace RGB value with avg
Color newColor = new Color(avg, avg, avg, color.getAlpha());
grayimg.setRGB(x, y, newColor.getRGB());
}
}
// write image
System.out.println("Trying to write the new image...");
File newf = new File("H:\\gray.jpg");
ImageIO.write(grayimg, "jpg", newf);
System.out.println("Finished writing the new image...");
} catch (IOException e) {
System.out.println(e);
}
}// main() ends here
}
If I understand this problem correctly, the important lesson here is that ImageIO.write(...) returns a boolean, indicating whether it succeeded or not. You should handle situations where the value is false, even if there is no exception. For reference, see the API doc.
Something like:
if (!ImageIO.write(grayimg, "JPEG", newf)) {
System.err.println("Could not store image as JPEG: " + grayimg);
}
Now, for the reason your code does indeed work in one JRE and not in another, is probably related to the image being of type TYPE_INT_ARGB (ie. contains alpha channel). This used to work in Oracle JDK/JREs but support was removed:
Previously, the Oracle JDK used proprietary extensions to the widely used IJG JPEG library in providing optional color space support.
This was used to support PhotoYCC and images with an alpha component on both reading and writing. This optional support has been removed in Oracle JDK 11.
The fix is easy; as your source is a JPEG file, it probably does not contain an alpha component anyway, so you could change to a different type with no alpha. As you want a gray image, I believe the best match would be:
BufferedImage grayimg = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
But TYPE_INT_RGB or TYPE_3BYTE_BGR should work too, should you later run into the same problem with color images.
Okay so I have spent about 15 hours trying to figure this out. I am working on this program that gets exported to a non-runnable jar file. The issue is I am trying to load an image in the jar and set it to a variable.
I HAVE looked at other posts and I think I have tried everything I could find but nothing seems to work.
I am not asking how to FIND the image as I can get the URL of the image, but then ImageIO.read(URL) is not throwing any exception, but returning null. The image is a .png which I have heard is compatible with ImageIO.read(). I am using an API so that is what the log() lines are.
Any help is appreciated. Thank you!
My Project:
Project
->src
-->package
--->Main.java
--->paint.png
My Code:
In my main method:
(mainPaint is a private Image)
mainPaint = getImage("paint.png");
The method:
private Image getImage(String fileName) {
URL url = getClass().getResource(fileName);
BufferedImage image = null;
log(url.toString()); // To make sure I have the correct file
// returning jar:file:/C:/Users/Me/MyJar.jar!/package/paint.png
try {
image = ImageIO.read(url);
} catch (IOException e1) {
log("Error converting url to image.");
// This is not happening
}
if (image == null) {
log("Image is null.");
// This is happening
}
return image;
}
Is the URL invalid? Am I just missing something? I'm just trying to save the local image in the jar as an Image object, I feel like this is way too difficult for what I am trying to do.
EDIT:
I also just tried making mainPaint a BufferedImage and using:
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource(fileName));
if(image == null) {
log("Image is null");
}
log("Height: " + image.getHeight(null));
log("Width: " + image.getWidth(null));
BufferedImage bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
// Draw the image on to the buffered image
Graphics2D bGr = bimage.createGraphics();
bGr.drawImage(image, 0, 0, null);
bGr.dispose();
// Return the buffered image
return bimage;
The height and width of the image are returning -1?
ImageIO.read() will not load SVG files, so if your images are in SVG formate you will need to add plugins to it to support SVG
Here is another SO post that explain where you can do that.
ImageIO.read() will load only GIF, PNG, JPEG, BMP, and WBMP image types.
Any other image type will return null without error.
It could answer to your question .
I am working with a Java to create a small applet. I am interested if there is a way I can "scan" an image to get the color values of a certain pixel. I would prefer to not have to display the image on the screen, but if you find that is the only way, please tell me. I would ideally like to be able to have my applet scan an image file and create an image on the screen according to the image. Please try to keep the answers a little bit simple, as I am still getting used to all of the technical terms.
Thanks,
~Rane
What I have so far:
import java.applet.Applet;
public class LoadGuideImage {
Applet applet;
public LoadGuideImage(Applet applet){
this.applet = applet;
}
public String getPixelColor(String pathToImage, int Xpix, int Ypix){
int redC = 0;
int greenC = 0;
int blueC = 0;
//Get Pixel colors here and save to ints
return redC + " " + greenC + " " + blueC;
}
}
Are you suggesting something like this 'the other guy'?:
BufferedImage img = (BufferedImage) getImage(pathToImage);
System.out.println("Color: " + img.getRGB(3, 3));
getImage method:
public Image getImage(String path) {
Image img;
URL url = null;
try {
url = applet.getDocumentBase();
} catch (Exception e){
// TODO: handle exception
}
img = applet.getImage(url, path);
return img;
}
nice name by the way. So I was in the same position a while ago.
use this for your get image method, just tweak it and use it to benefit you:
public class ImageLoader {
public BufferedImage load(String path){
try {
return ImageIO.read(getClass().getResource(path));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
I have a been making a game that uses individual pixels to load those pixels and then put tiles where certain pixels are located in the map. If you would like to take my code snippet from there let me know and ill hook you up :P
I have a web application written in Java (Spring, Hibernate/JPA, Struts2) where users can upload images and store them in the file system. I would like to scale those images so that they are of a consistent size for display on the site. What libraries or built in functions will offer the best results? I will consider the following criteria in making my decision (in this order):
Free/Open Source (essential)
Easy to implement
Quality of results
Performance
Size of executable
I would really recommend giving imgscalr a look.
It is released under an Apache 2 license, hosted on GitHub, been deployed in a handful of web applications already, has a very simple, but pedantically documented API, has code that works around 2 major image bugs in the JDK for you transparently that you'll only ever notice if you suddenly start getting "black" images after a scale operation or horrible-looking results, gives you the best possible looking results available in Java, is available via Maven as well as a ZIP and is just a single class.
Basic use looks like this:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, 320);
This is the simplest call where the library will make a best-guess at the quality, honor your image proportions, and fit the result within a 320x320 bounding box. NOTE, the bounding box is just the maximum W/H used, since your image proportions are honored, the resulting image would still honor that, say 320x200.
If you want to override the automatic mode and force it to give you the best-looking result and even apply a very mild anti-alias filter to the result so it looks even better (especially good for thumbnails), that call would look like:
BufferedImage img = ImageIO.read(...); // load image
BufferedImage scaledImg = Scalr.resize(img, Method.QUALITY,
150, 100, Scalr.OP_ANTIALIAS);
These are all just examples, the API is broad and covers everything from super-simple use cases to very specialized. You can even pass in your own BufferedImageOps to be applied to the image (and the library automatically fixes the 6-year BufferedImageOp JDK bug for you!)
There is a lot more to scaling images in Java successfully than the library does for you, for example always keeping the image in one of the best supported RGB or ARGB image types while operating on it. Under the covers the Java2D image processing pipeline falls back to an inferior software pipeline if the image type used for any image operations is poorly supported.
If all that sounded like a lot of headaches, it sort of is... that's why I wrote the library and open-sourced it, so folks could just resize their images and move on with their lives without needing to worry about it.
Hope that helps.
Have a look at the Java Image I/O API to read/write the image. Then use AffineTransform to resize.
Also, here's a complete example using java.awt.Image.
Look into also to java-image-scaling library. It created better quality images that ImageIO.
The best tool for image editing is ImageMagick and it is open source.
There are two interfaces for the Java Language:
JMagick which uses JNI interface to ImageMagick
and
im4java what is a command line interface for ImageMagick
Found this to be faster:
public static BufferedImage getScaledInstance(final BufferedImage img, final int targetWidth, final int targetHeight,
final Object hint) {
final int type = BufferedImage.TYPE_INT_RGB;
int drawHeight = targetHeight;
int drawWidth = targetWidth;
final int imageWidth = img.getWidth();
final int imageHeight = img.getHeight();
if ((imageWidth <= targetWidth) && (imageHeight <= targetHeight)) {
logger.info("Image " + imageWidth + "/" + imageHeight + " within desired scale");
return img;
}
final double sar = ((double) imageWidth) / ((double) imageHeight);
if (sar != 0) {
final double tar = ((double) targetWidth) / ((double) targetHeight);
if ((Math.abs(tar - sar) > .001) && (tar != 0)) {
final boolean isSoureWider = sar > (targetWidth / targetHeight);
if (isSoureWider) {
drawHeight = (int) (targetWidth / sar);
}
else {
drawWidth = (int) (targetHeight * sar);
}
}
}
logger.info("Scaling image from " + imageWidth + "/" + imageHeight + " to " + drawWidth + "/" + drawHeight);
final BufferedImage result = new BufferedImage(drawWidth, drawHeight, type);
try {
final Graphics2D g2 = result.createGraphics();
try {
if (hint != null) {
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
}
g2.drawImage(img, 0, 0, drawWidth, drawHeight, null);
}
finally {
g2.dispose();
}
return result;
}
finally {
result.flush();
}
}
I know this is a very old question, but I got my own solution for this using standard Java API
import java.awt.*;
import java.awt.event.*;
import javax.imageio.*
import java.awt.image.*;
BufferedImage im, bi, bi2;
Graphics2D gfx;
int imWidth, imHeight, dstWidth, dstHeight;
int DESIRED_WIDTH = 500, DESIRED_HEIGHT = 500;
im = ImageIO.read(new File(filePath));
imWidth = im.getWidth(null);
imHeight = im.getHeight(null);
dstWidth = DESIRED_WIDTH;
dstHeight = (dstWidth * imHeight) / imWidth;
bi = new BufferedImage(dstWidth, dstHeight, im.getType());
gfx = bi.createGraphics();
gfx.drawImage(im, 0, 0, dstWidth, dstHeight, 0, 0, imWidth, imHeight, null);
bi2 = new BufferedImage(DESIRED_WIDTH, DESIRED_HEIGHT, im.getType());
gfx = bi2.createGraphics();
gfx.drawImage(bi, 0, 0, DESIRED_WIDTH, DESIRED_HEIGHT, null);
ImageIO.write(bi2, "jpg", new File(filePath));
I am sure it can be improved and adapted.
I tried imgscalr comparing to standard Java 1.6 and I cannot say it is better.
What I've tried is
BufferedImage bufferedScaled = Scalr.resize(sourceImage, Method.QUALITY, 8000, height);
and
Image scaled = sourceImage.getScaledInstance(-1, height, Image.SCALE_SMOOTH);
BufferedImage bufferedScaled = new BufferedImage(scaled.getWidth(null), scaled.getHeight(null), BufferedImage.TYPE_INT_RGB);
bufferedScaled.getGraphics().drawImage(scaled, 0, 0, null);
some 5 minute testing by my eye got impression that second thing (pure Java 1.6) produces better results.