So I'm making a stopmotion application - the live feed from my webcam is inside a JPanel (with setOpaque(false)) that is inside the top (10th) layer in a JLayeredPane - and basically, when I take a picture, I want to add it to one of the lower layers so that a trace of the previous pictures you've taken shows up on screen. Here's how I'm trying to do that now:
EDIT: this is my new code based off the answer below - this now does nothing, as opposed to just adding the opaque image as before - if I add this to a JPanel, though, and add the JPanel to the JLayeredPane, then all I get is gray
BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img2.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
g.drawImage(img2, 0, 0, null);
g.dispose();
ImageIcon imgIcon = new ImageIcon(new ImageIcon(img2).getImage().getScaledInstance(img2.getWidth(), img2.getHeight(), Image.SCALE_SMOOTH));
JLabel showPic = new JLabel(imgIcon);
showPic.setSize(layers.getSize());
showPic.setBounds(layers.getX() + 18, layers.getY(), img2.getWidth(), img2.getHeight());
layers.add(showPic, new Integer(1)); //layers is my JLayeredPane
layers.repaint();
layers.revalidate();
img is the picture I've just captured from my webcam, and I'm trying to make it semi transparent, then add it to a JLabel. How can I make this work? Or is there a better way to do this?
I don't know if this will solve the problem but the image you are looking for is
BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
java.awt.Transparency.TRANSLUCENT has the value of 3 and corresponds to BufferedImage.TYPE_INT_ARGB_PRE which only god knows what it's doing.
With BufferedImage.TYPE_INT_ARGB you can create a transparent image and apply Composite etc
You also need to correct this
g.drawImage(img2, null, 0, 0);
to
g.drawImage(img2, 0, 0, null);
--
Heres how transparency works for me:
I have two images bim and bim2 and I draw one on top of the other:
BufferedImage bim=null, bim2=null;
try {
bim=ImageIO.read(new File("...."));
bim2=ImageIO.read(new File("...."));
}
catch (Exception ex) { System.err.println("error in bim "+ex); }
int wc=bim.getWidth(), hc=bim.getHeight();
BufferedImage img2 = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img2.createGraphics();
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
g.drawImage(bim, 0, 0, null);
g.drawImage(bim2, 0, 0, wc, hc, null);
Then I can display it on a JPanel Jframe or whatever.
I can even create the Label:
JLabel showPic = new JLabel(new ImageIcon(img2));
JFrame f=new JFrame();
f.setSize(500, 500);
f.add(showPic);
f.setVisible(true);
Related
I'm working on swing project.
I've jErrorMsgLabel to show error message.
I want to use L&F icons for jErrorMsgLabel same as below snap showing information message "Please specify a value for Database:"
So I did
jErrorMsgLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon"));`
But icon size is same as JOptionPane
How can I change icon size?
Or is there any other way around to show error messages?
You need to scale the image yourself:
ImageIcon icon = (ImageIcon)UIManager.getIcon("OptionPane.errorIcon");
Image image = icon.getImage();
Image scaledImage = image.getScaledInstance(80, 80, Image.SCALE_DEFAULT);
Icon scaledIcon = new ImageIcon( scaledImage );
yourLabel.setIcon( scaledIcon );
Of course whenever you scale an image larger you will get pixilation.
Edit:
Following is the code that paints the Icon to a BufferedImage which can then be scaled:
Icon icon = UIManager.getIcon("OptionPane.errorIcon");
BufferedImage bufferedImage = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bufferedImage.createGraphics();
icon.paintIcon(null, g, 0, 0);
g.dispose();
ImageIcon errorIcon = new ImageIcon(bufferedImage.getScaledInstance(15, 15, Image.SCALE_SMOOTH));
by using Canvas and JS I can draw a shape like this and have the x,y of each point :
Tha area can be choosen by more than 4 points, look at this link to have an idea.
I need to save and crop the image of the selected area by using the points. I can not use BufferedImage as it is just rectangular. Which lib in java I can use?
Okay, so starting with...
I used...
BufferedImage source = ImageIO.read(new File("Example.jpg"));
GeneralPath clip = new GeneralPath();
clip.moveTo(65, 123);
clip.lineTo(241, 178);
clip.lineTo(268, 405);
clip.lineTo(145, 512);
clip.closePath();
Rectangle bounds = clip.getBounds();
BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
clip.transform(AffineTransform.getTranslateInstance(-65, -123));
g2d.setClip(clip);
g2d.translate(-65, -123);
g2d.drawImage(source, 0, 0, null);
g2d.dispose();
ImageIO.write(img, "png", new File("Clipped.png"));
to generate...
Now, the image is rectangular, that's just the way it works
Now, setClip is quite rough and isn't effect by any RenderingHints, you could make use of "soft clipping" instead, which is more involved, but generates a nicer results. See this example and this exmaple for more details
I'm trying to make a picture fit a JLabel. I wish to reduce the picture dimensions to something more appropriate for my Swing JPanel.
I tried with setPreferredSize but it doesn't work.
I'm wondering if there is a simple way to do it? Should I scale the image for this purpose?
Outline
Here are the steps to follow.
Read the picture as a BufferedImage.
Resize the BufferedImage to another BufferedImage that's the size of the JLabel.
Create an ImageIcon from the resized BufferedImage.
You do not have to set the preferred size of the JLabel. Once you've scaled the image to the size you want, the JLabel will take the size of the ImageIcon.
Read the picture as a BufferedImage
BufferedImage img = null;
try {
img = ImageIO.read(new File("strawberry.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
Resize the BufferedImage
Image dimg = img.getScaledInstance(label.getWidth(), label.getHeight(),
Image.SCALE_SMOOTH);
Make sure that the label width and height are the same proportions as the original image width and height. In other words, if the picture is 600 x 900 pixels, scale to 100 X 150. Otherwise, your picture will be distorted.
Create an ImageIcon
ImageIcon imageIcon = new ImageIcon(dimg);
You can try it:
ImageIcon imageIcon = new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT));
label.setIcon(imageIcon);
Or in one line:
label.setIcon(new ImageIcon(new ImageIcon("icon.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT)));
The execution time is much more faster than File and ImageIO.
I recommend you to compare the two solutions in a loop.
public static void main(String s[])
{
BufferedImage image = null;
try
{
image = ImageIO.read(new File("your image path"));
} catch (Exception e)
{
e.printStackTrace();
}
ImageIcon imageIcon = new ImageIcon(fitimage(image, label.getWidth(), label.getHeight()));
jLabel1.setIcon(imageIcon);
}
private Image fitimage(Image img , int w , int h)
{
BufferedImage resizedimage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0,w,h,null);
g2.dispose();
return resizedimage;
}
The best and easy way for image resize using Java Swing is:
jLabel.setIcon(new ImageIcon(new javax.swing.ImageIcon(getClass().getResource("/res/image.png")).getImage().getScaledInstance(200, 50, Image.SCALE_SMOOTH)));
For better display, identify the actual height & width of image and resize based on width/height percentage
i have done the following and it worked perfectly
try {
JFileChooser jfc = new JFileChooser();
jfc.showOpenDialog(null);
File f = jfc.getSelectedFile();
Image bi = ImageIO.read(f);
image1.setText("");
image1.setIcon(new ImageIcon(bi.getScaledInstance(int width, int width, int width)));
} catch (Exception e) {
}
Or u can do it this way. The function u put the below 6 lines will throw an IOException. And will take your JLabel as a parameter.
BufferedImage bi=new BufferedImage(label.width(),label.height(),BufferedImage.TYPE_INT_RGB);
Graphics2D g=bi.createGraphics();
Image img=ImageIO.read(new File("path of your image"));
g.drawImage(img, 0, 0, label.width(), label.height(), null);
g.dispose();
return bi;
public void selectImageAndResize(){
int returnVal = jFileChooser.showOpenDialog(this); //open jfilechooser
if (returnVal == jFileChooser.APPROVE_OPTION) { //select image
File file = jFileChooser.getSelectedFile(); //get the image
BufferedImage bi;
try {
//
//transforms selected file to buffer
//
bi=ImageIO.read(file);
ImageIcon iconimage = new ImageIcon(bi);
//
//get image dimensions
//
BufferedImage bi2 = new BufferedImage(iconimage.getIconWidth(), iconimage.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
iconimage.paintIcon(null, g, 0,0);
g.dispose();
//
//resize image according to jlabel
//
BufferedImage resizedimage=resize(bi,jLabel2.getWidth(), jLabel2.getHeight());
ImageIcon resizedicon=new ImageIcon(resizedimage);
jLabel2.setIcon(resizedicon);
} catch (Exception ex) {
System.out.println("problem accessing file"+file.getAbsolutePath());
}
}
else {
System.out.println("File access cancelled by user.");
}
}
Assign your image to a string.
Eg image
Now set icon to a fixed size label.
image.setIcon(new javax.swing.ImageIcon(image.getScaledInstance(50,50,WIDTH)));
http://image.ohozaa.com/view/6fcjh
How to do this with Java Source code
I can merge that
but i can not to connect that like this pictue
Another approach would be to combine multiple Icons into a single Icon. See Compound Icon.
Put each image in an ImageIcon, then each Icon in a JLabel, and then add both JLabels to a JPanel that uses GridLayout(2, 1) (2 rows, 1 column).
File path = new File("images");
BufferedImage image = ImageIO.read(new File(path, "1 (1).jpg"));
BufferedImage overlay = ImageIO.read(new File(path, "1 (2).jpg"));
int w = image.getWidth();
int h = image.getHeight()+ overlay.getHeight();
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, image.getHeight(), null);
ImageIO.write(combined, "PNG", new File(path, "combined 2.png"));
I am looking for an easy way to render a String into a rectangular box within a JPG whereas line breaks should happen automatically for that text box.
Is this possible with Graphics2D ?
Rendering a string on a single line is easy, the following code snippet uses Antialiasing as well as a good JPG output compression quality:
BufferedImage img = ImageIO.read(new File(".../input.jpg"));
int width = img.getWidth();
int height = img.getHeight();
Color zgColor = new Color(0xAB,0x3C,0x2E);
Color grey = new Color(0xCC,0xCC,0xCC);
BufferedImage bufferedImage = new BufferedImage(width, height, img.getType());
Graphics2D g = bufferedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// draw graphics
g.drawImage(img, 0, 0, null);
g.setColor(zgColor);
int y = 900;
int x = 50;
g.setFont(new Font("Arial", Font.BOLD, 80));
g.drawString("Demo Text", x, y);
y+=80;
g.setColor(Color.WHITE);
g.setFont(new Font("Arial", Font.BOLD, 60));
g.drawString("Some other text a bit below", x, y);
y+=400;
g.setFont(new Font("Arial", Font.BOLD, 30));
g.setColor(Color.WHITE);
g.drawString("AND THIS WOULD BE THE TEXT I'D LIKE TO FIT INTO A BOX WITH AUTOMATIC LINE BREAKS", x, y);
g.dispose();
// Save as high quality JPEG
File targetFile = new File(".......result.jpg");
//ImageIO.write(bufferedImage, "jpg", targetFile); // this would give bad quality!
Iterator iter = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iter.next();
ImageWriteParam iwp = writer.getDefaultWriteParam();
iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
iwp.setCompressionQuality(1); // best quality
FileImageOutputStream output = new FileImageOutputStream(targetFile);
writer.setOutput(output);
IIOImage image = new IIOImage(bufferedImage, null, null);
writer.write(null, image, iwp);
writer.dispose();
System.out.println("Done.");
Check out LineBreakMeasurer. The API has some example code to get you started.
Or another approach is to create a JLabel with your image. Then you can add a JTextArea to the label and set the wrapping property on. Then the text will automatically wrap when you add the text area to the label. You will manually need to set the bounds of the text area within the label to control the placement of the text.