I am writing an image library for fun and i came across a problem that i can't seem to solve. The class is pretty simple: take a picture, process it, display it through JFrame, and finally save it as a BufferedImage (javax.imageio.ImageIO). Here is what my picture looks like through the JFrame (this is my ColorEnhance class... on the Drustan nebula):
Here is what the saved version (a png, but all types ImageIO.write() supports look the same):
I'm not sure where the change occurs, but when I run this through my blur method entire lines appear from nothing in the png... Anyways, here is some code:
public void writeToFile(BufferedImage finalPic, String nameToAppend)
{
String temp=fileName.replace(".", nameToAppend+".");
String ext=fileName.substring(fileName.indexOf(".")+1);
File file=new File(temp);
try
{
ImageIO.write(finalPic, ext.toUpperCase(), file);
System.out.println("Successfully saved to: "+temp);
} catch (Exception e) { e.getMessage(); }
}
public void displayImage(String titleName)
{
ImageIcon icon = new ImageIcon(newPic);
JFrame frame = new JFrame(titleName);
JLabel label = new JLabel(icon);
label.setIcon(icon);
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.setSize(WIDTH, HEIGHT+22);
frame.setVisible(true);
}
One last thing is that the save works for some processing classes better than others, if you need to see any more code just ask, thanks
Try using PNGImageEncoder from Apache XML Graphics Commons:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
PNGImageEncoder encoder = new PNGImageEncoder(new FileOutputStream("file.png"), null);
encoder.encode((RenderedImage) image);
Related
I'm trying to get the image file path or file name of an ImageIcon. I've created a screen in my Java gui app, which contains properties for a custom JButton (extends JButton). From that screen I'm setting some of the main button properties, as if it is enabled, focusable and its ImageIcon. The problem is that as if now, whenever I use this button class, which is in every screen btw, I'm loading all possible images for ImageIcons when the exdened JButton class is used. That causes the screen to freeze before any of the components are shown, while the images are loaded from classpath. In order to change that, in the settings screen, where I hava a JComboBox, containing all images for icons, there, at least that's what I can think of, should be a way to get only the name of the chosen ImageIcon- image path.
The buttons properties are stored in a properties file and that's where I intend to store the .png images names if I can get to them. The idea is to set the image name and when the button is loaded to the screen to look for and load only the image it's supposed to.
Here is a snipet of the button class now; The images are way more, but for demo purposes, I think those are enough. I'd be very grateful if anyone can help with this matter.
public class CustomButton extends JButton {
static Properties FieldProp;
public CustomButton (String text, String name) {
FieldProp = new LoadProperties().loadMainProp();
this.setText(text);
this.setName(name);
Image imgdel=null;
Image imgsmbl=null;
Image imgsmrd=null;
Image imgsmgr=null;
Image imgadd=null;
Image imgauto=null;
Image imgauto1=null;
Image imgavail=null;
Image imgbarc=null;
Image imgdb=null;
Image imgdoc=null;
Image imgexc=null;
Image imgexc1=null;
try {
imgdel = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/delete.png")));
imgsmbl = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/small_blue.png")));
imgsmrd = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/small_red.png")));
imgsmgr = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/small_green.png")));
imgadd = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/add_plus.png")));
imgauto = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/automation.png")));
imgauto1 = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/automation1.png")));
imgavail = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/available.png")));
imgbarc = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/barcode.png")));
imgdb = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/db.png")));
imgdoc = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/doc.png")));
imgexc = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/excel.png")));
imgexc1 = ImageIO.read(Objects.requireNonNull(getClass().getResource("/img/import.png")));
} catch (NullPointerException e) {
JOptionPane.showMessageDialog(null,e+"\n"+e.getMessage()+"\n"+ Arrays.toString(e.getStackTrace()),"",JOptionPane.ERROR_MESSAGE);
} catch (IOException e) {
JOptionPane.showMessageDialog(null,e+"\n"+e.getMessage()+"\n"+ Arrays.toString(e.getStackTrace()),"",JOptionPane.ERROR_MESSAGE);
}catch (Exception e) {
JOptionPane.showMessageDialog(null,e+"\n"+e.getMessage()+"\n"+ Arrays.toString(e.getStackTrace()),"",JOptionPane.ERROR_MESSAGE);
}
ImageIcon delIcon = new ImageIcon(imgdel);
ImageIcon blIcon = new ImageIcon(imgsmbl);
ImageIcon rdIcon = new ImageIcon(imgsmrd);
ImageIcon grIcon = new ImageIcon(imgsmgr);
ImageIcon addIcon = new ImageIcon(imgadd);
ImageIcon autoIcon = new ImageIcon(imgauto);
ImageIcon autoIcon1 = new ImageIcon(imgauto1);
ImageIcon availIcon = new ImageIcon(imgavail);
ImageIcon barcIcon = new ImageIcon(imgbarc);
ImageIcon dbIcon = new ImageIcon(imgdb);
ImageIcon docIcon = new ImageIcon(imgdoc);
ImageIcon excIcon = new ImageIcon(imgexc);
ImageIcon excIcon1 = new ImageIcon(imgexc1);
Object[] items =
{
noIcon,
delIcon,
blIcon,
rdIcon,
grIcon,
addIcon,
autoIcon,
autoIcon1,
availIcon,
barcIcon,
dbIcon,
docIcon,
excIcon,
excIcon1
};
try {
int iconPosition = Integer.parseInt(FieldProp.getProperty(this.getName() + "Icon"));
String iconProp = FieldProp.getProperty(this.getName() + "Icon");
if (!iconProp.equals("0")) {
this.setIcon((ImageIcon) items[iconPosition]);
}
}catch (Exception e){
e.printStackTrace();
}
try {
this.setEnabled((Boolean.parseBoolean(FieldProp.getProperty(this.getName() + "Enabled"))));
this.setFocusable((Boolean.parseBoolean(FieldProp.getProperty(this.getName() + "Focusable"))));
}catch(Exception e){}
I can't load image into BufferedImage Object with new File() without full path of the image.
When i'm trying to load an image.png into BufferedImage Object with new File() I face to results:
Success - when I write the whole path (C://Users//benja//Desktop/...) it works fine
Fail - when i write the path of the image that i have imported into my project. Is there a way to make it work even if i'm using new File(...)?
public class PicturePanel extends JPanel {
BufferedImage image=null;
public PicturePanel() {
try {
image = ImageIO.read(new
/*Works fine with full path: */
File("C://Users//benjamin//Desktop//Pictures//whiteFish.png"));
/*fail - throw an exception: */
//image = ImageIO.read(new
File("//RandomThingsInGui/whiteFish.png"));
} catch (IOException e) { e.printStackTrace(); }
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0,0,500,250,null);
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.add(new PicturePanel());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setSize(600,400);
f.setVisible(true);
}
What i need is to know if there is a way (and how) to load the image from an imported path (I mean from inside eclipse) or when I use new File(...) I must use full path.
thanks for helpers :)
Copy the 'whiteFish.png' file to the 'RandomThingsInGui' directory.
Can you try this?
try {
// AS-IS
//image = ImageIO.read(new File("//RandomThingsInGui/whiteFish.png"));
// TO-BE (replace '//' to '/')
image = ImageIO.read(new File("/RandomThingsInGui/whiteFish.png"));
} catch (IOException e) {
e.printStackTrace();
}
I am trying to create a simple application which can take an image from web cam and display it in a jlabel. but I is not working. I can't understand the reason. my complete project uploaded to here.
I use this library to take the image, following code does it.
// get default webcam and open it
Webcam webcam = Webcam.getDefault();
webcam.open();
// get image
BufferedImage image = webcam.getImage();
try {
// save image to PNG file
ImageIO.write(image, "PNG", new File("test.png"));
} catch (IOException ex) {
Logger.getLogger(TestFrame.class.getName()).log(Level.SEVERE, null, ex);
}
webcam.close();
after taking the image I wrote the following code to display the image to jlabel
String path = "test.png";
imageLbl.setIcon(null);
imageLbl.setIcon(new ImageIcon(path));
imageLbl.revalidate();
imageLbl.repaint();
imageLbl.update(imageLbl.getGraphics());
if there is an image already then it will display to the jlabel. but most reasonlly taken image is not shown. it's hard to explain the situation, I appreciate if you can download and check my project here.
You can use below code to dynamically update image to jlabel.
String path = "test.png";
imageLbl.setIcon(null);
try {
BufferedImage img=ImageIO.read(new File(path));
imageLbl.setIcon(new ImageIcon(img));
imageLbl.revalidate();
imageLbl.repaint();
imageLbl.update(imageLbl.getGraphics());
} catch (IOException ex) {
}
I have created a custom JButton where override the setIcon.
public class TestButton extends JButton {
public TestButton() {
super();
}
#Override
public void setIcon(Icon icon) {
super.setIcon(icon);
imgToBufferedImg(Toolkit.getDefaultToolkit().createImage("test.png"));
}
}
And here is the imgToBufferedImg method.
public BufferedImage imgToBufferedImg(Image image) {
if (image == null) {
return null;
}
if (image instanceof BufferedImage) {
return ((BufferedImage) image);
} else {
BufferedImage bufferedImage = new BufferedImage(
image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return bufferedImage;
}
}
I have added this component in Matisse, no problem, however, when i try to set the icon property of the button i get the error:
Failed to write the value to the property "icon"
The problem seems to come from the imgToBufferedImg since i can set the property if i remove the call to this method in setIcon. What is wrong with my image conversion method?
EDIT:
The following test succeeded:
try {
imgToBufferedImg(ImageIO.read(new FileInputStream("test.png")));
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
Also i just figured out that the problem is caused by:
((ImageIcon) icon).getImage();
Running this code when the UI is ready (e.g using a SwingUtilities.invokeLater) seems to work.
The problem might be in Toolkit#createImage(). ImageIO.read() might be better. Also, it looks like you're throwing away the result from imgToBufferedImg().
no reason why
create BufferedImage inside JButtons setIcon(), there you would be to set (for JButton) Icon, ImageIcon
this BufferedImage (should be Icon, ImageIcon) is create after is added to JButton
but
method could be BufferedImage to Icon, ImageIcon
whats wrong with JButton#setIcon()
you can use paintComponent() too
Thanks to the thrashed comment:
Toolkit "operations may be performed asynchronously." Your Image may be incomplete when you try to render it.
I was able to figure out what the problem was. Straight from the setIcon method, i requested the image from the icon:
((ImageIcon) icon).getImage()
But this image is definitively incomplete. Putin my logic within the event dispatching thread did the trick.
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
//requesting icon images here
}
}
I am currently trying to resize a picture that I am downloading from the web and putting it into a JPanel.
First, I am using the following code to download the image from the web:
public static Image MSImageHigh(){
URL imageUrl = null;
try {
imageUrl = new URL("http://www.hmdb.ca/labm/metabolites/"
+ HMDB + "/ms/spectraH/" + HMDB + "H.png");
} catch (MalformedURLException e) {
e.printStackTrace();
}
Image image = Toolkit.getDefaultToolkit().createImage(imageUrl);
return image;
}
Then I made a new method that resizes the image:
public static BufferedImage resizeImage() {
final BufferedImage bufferedImage = new BufferedImage(300, 500,BufferedImage.TYPE_INT_RGB);
final Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.setComposite(AlphaComposite.Src);
graphics2D.drawImage(MSImageHigh(), 0, 0, 200, 200, null);
graphics2D.dispose();
return bufferedImage;
}
This should produce s a new image that is resized to 200x200 px. What it in fact does is give me a black screen that is 200x200px in size. Btw, I also tried using TYPE_INT_ARGB instead of TYPE_INT_RGB, and this produces a totally transparent image, so that is not working either.
I used ImageIO.read(imageUrl) instead of Toolkit.getDefaultToolkit().createImage(imageUrl) and that solved the problem. Thanks #Hovercraft Full Of Eels!