I want to display an image but don't know what to do. Whether I have to install some library files or simply it can be done I don't know. Actually I want to do image processing, but first I have to take the image input and display image then I can get the effect of image processing as the output and decide whether it(algorithm) is correct or not. I have installed the eclipse only. I have searched in Google also but whatever they suggest is not working well. Either I have to install something or not.
I have tried the following code:
public class ImageTest {
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
public void run(){
ImageFrame frame = new ImageFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
);
}
}
class ImageFrame extends JFrame{
public ImageFrame(){
setTitle("ImageTest");
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
ImageComponent component = new ImageComponent();
add(component);
getContentPane().validate();
getContentPane().repaint();
}
public static final int DEFAULT_WIDTH = 300;
public static final int DEFAULT_HEIGHT = 200;
}
class ImageComponent extends JComponent{
private static final long serialVersionUID = 1L;
private Image image;
public ImageComponent(){
try{
File image2 = new File("bishnu.jpg");
image = ImageIO.read(image2);
} catch (IOException e){
e.printStackTrace();
}
}
public void paintComponent (Graphics g){
if(image == null) return;
int imageWidth = image.getWidth(this);
int imageHeight = image.getHeight(this);
g.drawImage(image, 50, 50, this);
for (int i = 0; i*imageWidth <= getWidth(); i++)
for(int j = 0; j*imageHeight <= getHeight();j++)
if(i+j>0) g.copyArea(0, 0, imageWidth, imageHeight, i*imageWidth, j*imageHeight);
}
}
It simply shows a graphical window but can't show the image "bishnu.jpg"
Should I install anything in eclipse? But I think nothing needs to install.
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
public class DisplayImage {
public static void main(String avg[]) throws IOException
{
DisplayImage abc=new DisplayImage();
}
public DisplayImage() throws IOException
{
BufferedImage img=ImageIO.read(new File("f://images.jpg"));
ImageIcon icon=new ImageIcon(img);
JFrame frame=new JFrame();
frame.setLayout(new FlowLayout());
frame.setSize(200,300);
JLabel lbl=new JLabel();
lbl.setIcon(icon);
frame.add(lbl);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Running your code shows an image for me, after adjusting the path. Can you verify that your image path is correct, try absolute path for instance?
If you want to load/process/display images I suggest you use an image processing framework. Using Marvin, for instance, you can do that easily with just a few lines of source code.
Source code:
public class Example extends JFrame{
MarvinImagePlugin prewitt = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.edge.prewitt");
MarvinImagePlugin errorDiffusion = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.halftone.errorDiffusion");
MarvinImagePlugin emboss = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.color.emboss");
public Example(){
super("Example");
// Layout
setLayout(new GridLayout(2,2));
// Load images
MarvinImage img1 = MarvinImageIO.loadImage("./res/car.jpg");
MarvinImage img2 = new MarvinImage(img1.getWidth(), img1.getHeight());
MarvinImage img3 = new MarvinImage(img1.getWidth(), img1.getHeight());
MarvinImage img4 = new MarvinImage(img1.getWidth(), img1.getHeight());
// Image Processing plug-ins
errorDiffusion.process(img1, img2);
prewitt.process(img1, img3);
emboss.process(img1, img4);
// Set panels
addPanel(img1);
addPanel(img2);
addPanel(img3);
addPanel(img4);
setSize(560,380);
setVisible(true);
}
public void addPanel(MarvinImage image){
MarvinImagePanel imagePanel = new MarvinImagePanel();
imagePanel.setImage(image);
add(imagePanel);
}
public static void main(String[] args) {
new Example().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Output:
As a beginer, I found that is easy to see the picture you draw:
Source code
public class CheckCodeTest {
private int width = 100, height = 50;
private BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
#Test
public void drawGraphicsTest() throws IOException {
Graphics graphics = image.createGraphics();
// draw an orange rectangle
graphics.setColor(Color.orange);
graphics.fillRect(0,0,width,height);
// layout the picture right now!
graphics.drawImage(image,0,0,null);
ImageIO.write(image, "png", new File("checkcode.png"));
}
}
Output
It produce a picture file under your projects content.
output-picture
Then you can see what change after adding draw code in small window, it is more convenient than closing an jump-out Frame / Label window:
output-picture-in-editor
Hope it helps.
Related
I need to rotate ImageIcon to buffered image in Java. I've tried every possible way, is there any way, I already tried to convert ImageIcon to bufferedImage.
I tried every possible StackOverflow solution
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class Test {
public static void main(String[] args) {
// Create GUI
GUI gui = new GUI();
// Schedule task; rotate img every 1s
Timer timer = new Timer(1000, e -> gui.rotateImg());
timer.setRepeats(true);
timer.start();
}
static class GUI extends JFrame {
// Web url for image of cute doggo
private static final String IMAGE_URL = "https://i.pinimg.com/736x/10/b2/6b/10b26b498bc3fcf55c752c4e6d9bfff7.jpg";
// Cache image and UI components for rotation
private BufferedImage image;
private ImageIcon icon;
private JLabel label;
// Create new JFrame
public GUI() {
// Config grame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(700, 700);
setLocationRelativeTo(null);
URL url;
image = null;
try {
// Download + cache image from web
url = new URL(IMAGE_URL);
image = ImageIO.read(url);
} catch (IOException e) {
// Handle error downloading
System.out.println("Failed to read image due to: " + e.getMessage());
} finally {
// On success - create/cache UI components
if (image != null) {
// In this example I am using a label here to display an ImageIcon
// But at root the ImageIcon is holding a BufferedImage which is what we're modifying on rotation
add(label = new JLabel(icon = new ImageIcon(image)));
}
}
// Show configured JFrame
setVisible(true);
}
public void rotateImg() {
if (image == null) return;
// Rotate image
BufferedImage rotated = rotateImg(image, Math.toRadians(90));
// Add rotated image
icon.setImage(image = rotated);
// Repaint
label.revalidate();
label.repaint();
}
// SRC: https://www.delftstack.com/howto/java/java-rotate-image/
private BufferedImage rotateImg(BufferedImage img, double degrees) {
int w = img.getWidth(), h = img.getHeight();
BufferedImage imgCopy = new BufferedImage(w, h, img.getType());
Graphics2D g2d = imgCopy.createGraphics();
g2d.rotate(degrees, w / 2, h / 2);
g2d.drawImage(img, null, 0, 0);
return imgCopy;
}
}
}
So I'm currently having the problem that a large image will cover up smaller images in my program when i try to graphically display them in Java. I would like to know how to bring certain images to the front of the window so the large "background" image will stay in the background. Also, I do not believe it's a possibility in my program to simply implement the pictures in reverse order.
Here's the code I used:
my image manager class with the method I use to implement the images into the window,
import java.awt.*;
import javax.swing.*;
public class ImageManager extends JFrame {
private ImageIcon image1;
private JLabel label1;
private ImageIcon image2;
private JLabel label2;
private ImageIcon image3;
private JLabel label3;
public ImageManager() {
}
public void addBackground() {
image3 = new ImageIcon(getClass().getResource("background.png"));
label3 = new JLabel(image3);
add(label3);
}
public void addSeaweed() {
image1 = new ImageIcon(getClass().getResource("seaweed.png"));
label1 = new JLabel(image1);
add(label1);
}
public void addUnderwatervolcano() {
image2 = new ImageIcon(getClass().getResource("underwatervolcano.png"));
label2 = new JLabel(image2);
add(label2);
}
}
and here's where I use the methods from ImageManager:
a method to display a picture of seaweed using the grow() method,
public Seaweed() {
setLayout(new FlowLayout());
World.gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
World.gui.setVisible(true);
World.gui.pack();
World.gui.setTitle("seaweed and underwatervolcano");
carbon = 0;
}
public void grow() {
if(World.getOceanCarbon() >= 10) {
addCarbon(10);
World.addOceanCarbon(-10);
World.gui.addSeaweed();
World.gui.pack();
}
}
and heres the method in a different class that uses the grow() method from the Seaweed class and the gui.addBackground() from the ImageManager class,
public static void runWorld() {
gui.addBackground();
UnderwaterVolcano volcano = new UnderwaterVolcano();
Seaweed seaweed = new Seaweed();
volcano.erupt();
seaweed.grow();
gui.setMinimumSize(new Dimension(905, 560));
}
}
i would like to know how i make it so gui.addBackground() does not cover up the picture of seaweed from gui.addSeaweed() (which was invoked in the seaweed.grow() method) while still invoking gui.addBackground() before invoking gui.addSeaweed(). Is there anyway I can manipulate at the method call the order in which images display in a window? I don't have a very good understanding of JFrame so please be very explanatory with your answers, all help appreciated.
Well your current logic adds all the images to the frame. Swing actually paints the last component added first. That is components are painted based on highest ZOrder being painted first. The default ZOrder of the component is simply the component count at the time the component is added to the panel. So yes based on your current logic the background will paint over top of the other images.
A couple of simple solutions:
1) Manage the ZOrder of your components.
After you add the component to frame you can reset the ZOrder so the component is painted last. So the basic code is
add(aComponent);
setComponentZOrder(aComponent, 0);
2) Add the child images to the background image instead of add all images to the frame. So you have a structure like:
- frame
- background image
- seaweed
- volcano
So the basic logic would be something like:
frame.add( background );
background.add( seaweed );
background.add( volcano );
Since in looks like the seaweed/volcano images are at random places on the background you would still need to manage the size/location of each of these images.
Note when adding child components to the background the child components must be fully contained within the background image or the child image will be truncated.
This is the approach I would use since it better describes the structure of your application. That is your frame contains a background and the background contains other child components. Nesting of components is common to get a desired layout of a frame.
You have to use a LayeredPane. Here is a working example of my own. You only have to replace the used images by some of yours.
The Main class:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Main{
static JFrameWin jFrameWindow;
public static void main(String[] args) {
SwingUtilities.invokeLater(runJFrameLater);
}
public static class JFrameWin extends JFrame{
public JFrameWin(){
// init
initJFrame(this);
JPanelSettings jPanelSettings = new JPanelSettings(this.getWidth(), this.getHeight(), this.getX(), this.getY());
JLayeredPane enclosingJLayeredPane = getEnclosingJLayeredPane(jPanelSettings);
jPanelSettings = new JPanelSettings(this.getWidth(), this.getHeight(), this.getX(), this.getY(), new File("billard_1.jpg"));
JPanel backgroundJPanel = getJPanel(jPanelSettings);
jPanelSettings = new JPanelSettings(this.getWidth()-100, this.getHeight()-100, this.getX()+5, this.getY()+20, new File("billard2.jpg"));
JPanel firstLayerJPanel = getJPanel(jPanelSettings);
jPanelSettings = new JPanelSettings(this.getWidth() - 200, this.getHeight() - 200, this.getX() + 60, this.getY() + 60, new File("painter.jpg"));
JPanel secondLayerJPanel = getJPanel(jPanelSettings);
// assemble
enclosingJLayeredPane.add(backgroundJPanel);
enclosingJLayeredPane.add(firstLayerJPanel);
enclosingJLayeredPane.add(secondLayerJPanel);
// adjust layers
enclosingJLayeredPane.setLayer(backgroundJPanel, 0);
enclosingJLayeredPane.setLayer(firstLayerJPanel, 1);
enclosingJLayeredPane.setLayer(secondLayerJPanel, 2);
// add object to JFrame
this.add(enclosingJLayeredPane, BorderLayout.CENTER);
}
}
static Runnable runJFrameLater = new Runnable() {
#Override
public void run() {
jFrameWindow = new JFrameWin();
jFrameWindow.setVisible(true);
}
};
private static void initJFrame(JFrame jFrame) {
jFrame.setTitle("Boxing Test");
jFrame.setSize(600, 600);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static JLayeredPane getEnclosingJLayeredPane(JPanelSettings jPanelSettings){
JLayeredPane jLayeredPane = new JLayeredPane();
jLayeredPane.setBounds(jPanelSettings.getXPosition(), jPanelSettings.getYPosition(), jPanelSettings.getWidth(), jPanelSettings.getHeight());
return jLayeredPane;
}
private static JPanel getJPanel(JPanelSettings jPanelSettings){
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(jPanelSettings.getImagePath());
} catch (IOException ex) {
System.out.println("Error" + ex.toString());
}
// fit image to frame size
Image scaledBufferedImage = bufferedImage.getScaledInstance(jPanelSettings.getWidth(), jPanelSettings.getHeight(), Image.SCALE_DEFAULT);
JLabel jLabel = new JLabel(new ImageIcon(scaledBufferedImage));
JPanel jPanel = new JPanel();
jPanel.setBounds(jPanelSettings.getXPosition(), jPanelSettings.getYPosition(), jPanelSettings.getWidth(), jPanelSettings.getHeight());
jPanel.add(jLabel);
return jPanel;
}
}
A helper-class
import java.io.File;
public class JPanelSettings {
private int height;
private int width;
private int xPosition;
private int yPosition;
private File imagePath;
// Basic constructor
public JPanelSettings(){ }
// size and positioning constructor
public JPanelSettings(int width,int height, int xPosition, int yPosition ){
setWidth(width);
setHeight(height);
setXPosition(xPosition);
setYPosition(yPosition);
}
// Full constructor
public JPanelSettings(int width,int height, int xPosition, int yPosition, File imagePath ){
setWidth(width);
setHeight(height);
setXPosition(xPosition);
setYPosition(yPosition);
setImagePath(imagePath);
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getXPosition() {
return xPosition;
}
public void setXPosition(int xPosition) {
this.xPosition = xPosition;
}
public int getYPosition() {
return yPosition;
}
public void setYPosition(int yPosition) {
this.yPosition = yPosition;
}
public File getImagePath() {
return imagePath;
}
public void setImagePath(File imagePath) {
this.imagePath = imagePath;
}
}
I am trying to create a BackgroundImage class that has the purpose of creating a background with several image layers, I am using a JLayeredPane to achieve the layers.
The background image will hold a permanent base image and will have methods that allows me(hopefully) to fade in and out images upon this base image.
Right now i'm stuck at the base image being located wrong.
Here is a image that shows the problem:
As you can see in the image, there is a slight grey area above the image that is not supposed to be there. I would like the base image to take all the space.
Here is a MCVE:
BackgroundTest class
import java.awt.*;
import javax.swing.*;
final class BackgroundTest extends JFrame {
public static void main(String[] args) {
new BackgroundTest();
}
BackgroundTest() {
JPanel contentPanel = new JPanel();
BackgroundImage bgImage = new BackgroundImage(contentPanel);
add(contentPanel);
setSize(getScreenDimension());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static Dimension getScreenDimension() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = ge.getMaximumWindowBounds();
return new Dimension((int) bounds.getWidth(), (int) bounds.getHeight());
}
}
BackgroundImage class
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import org.imgscalr.Scalr;
class BackgroundImage {
private final BaseImage baseImage;
private final JPanel targetPanel;
private final JLayeredPane layeredPane;
BackgroundImage(JPanel targetPanel) {
this.targetPanel = targetPanel;
layeredPane = new JLayeredPane();
Dimension screenDimension = BackgroundTest.getScreenDimension();
layeredPane.setPreferredSize(screenDimension);
layeredPane.setMaximumSize(screenDimension);
layeredPane.setMinimumSize(screenDimension);
baseImage = new BaseImage();
layeredPane.add(baseImage, new Integer(0));
targetPanel.add(layeredPane);
}
public void addCharacterImageToBase(int characterIdentifier) {
}
public void replaceCurrentCharacterImage(int characterIdentifier) {
}
private class BaseImage extends JComponent {
private ImageIcon imageIcon;
private int imageWidth, imageHeight;
BaseImage() {
BufferedImage backgroundImage;
try {
Dimension screenSize = BackgroundTest.getScreenDimension();
imageWidth = screenSize.width;
imageHeight = screenSize.height;
setBounds(0, 0, imageWidth, imageHeight);
backgroundImage = ImageIO.read(getClass().getResource("/images/background/sky.jpg"));
if (imageWidth > 0 && imageHeight > 0) {
backgroundImage = Scalr.resize(backgroundImage, Scalr.Method.QUALITY, Scalr.Mode.FIT_EXACT, imageWidth, imageHeight, Scalr.OP_ANTIALIAS);
}
imageIcon = new ImageIcon(backgroundImage);
} catch (IOException e) {
Main.getLogger().log(java.util.logging.Level.INFO, e.getMessage(), e);
}
}
public int getImageWidth() {
return imageWidth;
}
public int getImageHeight() {
return imageHeight;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imageIcon.getImage(), 0, 0, imageWidth, imageHeight, this);
}
}
private class CharacterImage extends JComponent {
CharacterImage(int currentLevelNumber) {
}
}
}
Thank you for your time.
The answer is that your JPanel has a BorderLayout by default and its hgap and vgap are not 0.
You need this:
JPanel contentPanel = new JPanel(new BorderLayout(0,0));
For my application I need to dynamically create thumbnails of websites. So far I have this code from SO:
public class CreateWebsiteThumbnail {
private static final int WIDTH = 128;
private static final int HEIGHT = 128;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
public void capture(Component component) {
component.setSize(image.getWidth(), image.getHeight());
Graphics2D g = image.createGraphics();
try {
component.paint(g);
} finally {
g.dispose();
}
}
private BufferedImage getScaledImage(int width, int height) {
BufferedImage buffer = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffer.createGraphics();
try {
g.drawImage(image, 0, 0, width, height, null);
} finally {
g.dispose();
}
return buffer;
}
public void save(File png, int width, int height) throws IOException {
ImageIO.write(getScaledImage(width, height), "png", png);
}
public static void main(String[] args) throws IOException {
Shell shell = new Shell();
Browser browser = new Browser(shell, SWT.EMBEDDED);
browser.setUrl("http://www.google.com");
CreateWebsiteThumbnail cap = new CreateWebsiteThumbnail();
cap.capture(What her?);
cap.save(new File("foo.png"), 64, 64);
}
}
But as you can see here, I don't know which part of the browser I should pass to my capture method. Any hints?
I don't see, how the code you provided could work. The Shell is not opened, it has no size, the Browser didn't get time to actually load anything, no event loop seems to be running to enable any drawing, ...
The following code does a screenshot of a page using SWT browser:
import java.io.IOException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class CreateWebsiteThumbnail {
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
public static void main( String[] args ) throws IOException {
final Display display = new Display();
final Shell shell = new Shell();
shell.setLayout(new FillLayout());
final Browser browser = new Browser(shell, SWT.EMBEDDED);
browser.addProgressListener(new ProgressListener() {
#Override
public void changed( ProgressEvent event ) {}
#Override
public void completed( ProgressEvent event ) {
shell.forceActive();
display.asyncExec(new Runnable() {
#Override
public void run() {
grab(display, shell, browser);
}
});
}
});
browser.setUrl("http://www.google.com");
shell.setSize(WIDTH, HEIGHT);
shell.open();
while ( !shell.isDisposed() ) {
if ( !display.readAndDispatch() ) display.sleep();
}
display.dispose();
}
private static void grab( final Display display, final Shell shell, final Browser browser ) {
final Image image = new Image(display, browser.getBounds());
GC gc = new GC(browser);
gc.copyArea(image, 0, 0);
gc.dispose();
ImageLoader loader = new ImageLoader();
loader.data = new ImageData[] { image.getImageData() };
loader.save("foo.png", SWT.IMAGE_PNG);
image.dispose();
shell.dispose();
}
}
But there are some serious caveats:
You cannot do this off-screen. SWT screenshots are just a copy of the current Display.
The window containing your browser must be on top, when taking the screenshot.
The page should be visible after onLoad (which is actually not the case with google.com, but works for me because of the asyncExec call anyway - if you get a white image, try another URL)
The result is dependant on your OS and its installed browsers
I'd go with a non Java-solution, in order to get off screen drawing. I believe the linked question might help you to get further.
As far as I know, when you use a Browser object, the webpage you load is rendered directly on the Composite object you pass to it through the constructor. In your case, it is rendered on your Shell item which is a window-style object. There is no method to render the webpage directly on, say, an Image object.
You can try, though, to instantiate your Browser on a Canvas object and save the image directly from there.
Unfortunately I am unable to test whether this works or not because I have neither Eclipse nor SWT installed; I am pretty sure though that, if what you want to do is doable, this is the only way.
I did some experimenting myself. My intuition was to try on JEditorPane just like mentioned in the answer your code is based on. I do not know of how much help it is going to be but it might help. I gives some results, but from obvious reasons, luck of css support etc in JEditorPane it all looks ugly.
This is my code:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.html.HTMLEditorKit;
public class WebPageToImageThumbnail {
public static void main(String[] a) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JEditorPane editorPane = new JEditorPane();
editorPane.setEditorKit(new HTMLEditorKit());
try {
editorPane.setPage(new URL("http://weblogs.java.net/blog/alex2d/archive/2008/12/jwebpane_projec.html"));
} catch (IOException ex) {
}
final JPanel panel = new JPanel(new BorderLayout());
panel.add(new JScrollPane(editorPane), BorderLayout.CENTER);
panel.add(new JButton(new AbstractAction("SAVE") {
#Override
public void actionPerformed(ActionEvent e) {
BufferedImage image = capture(editorPane);
try {
save(image, new File("foo.png"), 64, 64);
} catch (IOException ex) {
}
}
}), BorderLayout.SOUTH);
frame.setContentPane(panel);
frame.setSize(600, 400);
frame.setVisible(true);
}
});
}
public static BufferedImage capture(Component component) {
BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);//component.setSize(image.getWidth(), image.getHeight());
Graphics2D g = image.createGraphics();
try {
component.paint(g);
} finally {
g.dispose();
}
return image;
}
private static BufferedImage getScaledImage(BufferedImage image, int width, int height) {
BufferedImage buffer = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffer.createGraphics();
try {
g.drawImage(image, 0, 0, width, height, null);
} finally {
g.dispose();
}
return buffer;
}
public static void save(BufferedImage image, File png, int width, int height) throws IOException {
ImageIO.write(getScaledImage(image, width, height), "png", png);
}
}
I also did some digging about the SWT I found some thinks that might be of use, but since I currently luck time, I cannot test. From what I read I have to agree with #Emanuele Bezzi (+1) that we are going to have to use the Shell somehow to get the content of the site, in which we are effectively only interested.
I found out that Shell has print method which takes GC object which can paint including to Image and other interesting to us stuff, the documentation says: "Class GC is where all of the drawing capabilities that are supported by SWT are located. Instances are used to draw on either an Image, a Control, or directly on a Display.".
Yet at this particular moment it is not clear to me how to exactly get it to do what I want. Anyway I am raising this point just to make you aware. I still need to look into it further.
Maybe you're better off rendering the page offscreen right from the start. For such a task you may for example use "flying saucer" (which is xhtml only, so you need to tidy up). There seem to be also some tools to interface Webkit directly from Java.
I have a Java project that's about traffic network simulation in a random city, I've managed to figure out a way to implement this project, so I divided each intersection into a section which is basically an extended JPanel class (named Carrefour)...everything works well until I got stuck with how to draw vehicles and make them pass through roads.
So my problem is how to draw an image (vehicle image) over an another image (road)?
Another approach that does not require extending components.
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;
import java.net.URL;
import javax.imageio.ImageIO;
public class ImageOnImage {
ImageOnImage(final BufferedImage bg, BufferedImage fg) {
final BufferedImage scaled = new BufferedImage(
fg.getWidth()/2,fg.getHeight()/2,BufferedImage.TYPE_INT_RGB);
Graphics g = scaled.getGraphics();
g.drawImage(fg,0,0,scaled.getWidth(),scaled.getHeight(),null);
g.dispose();
final int xMax = bg.getWidth()-scaled.getWidth();
final int yMax = bg.getHeight()-scaled.getHeight();
final JLabel label = new JLabel(new ImageIcon(bg));
ActionListener listener = new ActionListener() {
Random random = new Random();
public void actionPerformed(ActionEvent ae) {
Graphics g = bg.getGraphics();
int x = random.nextInt(xMax);
int y = random.nextInt(yMax);
g.drawImage( scaled, x, y, null );
g.dispose();
label.repaint();
}
};
Timer timer = new Timer(1200, listener);
timer.start();
JOptionPane.showMessageDialog(null, label);
}
public static void main(String[] args) throws Exception {
URL url1 = new URL("http://i.stack.imgur.com/lxthA.jpg");
final BufferedImage image1 = ImageIO.read(url1);
URL url2 = new URL("http://i.stack.imgur.com/OVOg3.jpg");
final BufferedImage image2 = ImageIO.read(url2);
//Create the frame on the event dispatching thread
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
new ImageOnImage(image2, image1);
}
});
}
}
If this is Swing, then draw the background image in a BufferedImage. Display this BufferedImage in a JComponent's (such as a JPanel's) paintComponent method using Graphic's drawImage(...) method, and then draw the changing images over this in the same paintComponent method. Don't forget to call the super.paintComponent(...) method first though.
Please note that this question has been asked quite a bit here and elsewhere, and as you would expect, there are lots of examples of this sort of thing that you can find here with a bit of searching.
Edit
You ask:
Thanks, this is how I draw the firt image (road)
Again, you would create a BufferedImage for this, likely by using ImageIO.read(...). Then you'd draw this in your JPanel's paintComponent(Graphics g) method override using g.drawImage(...).
For example...
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
#SuppressWarnings("serial")
public class IntersectionImagePanel extends JPanel {
private static final String INTERSECTION_LINK = "http://www.weinerlawoffice.com/" +
"accident-diagram.jpg";
private BufferedImage intersectionImage;
public IntersectionImagePanel() {
URL imageUrl;
try {
imageUrl = new URL(INTERSECTION_LINK);
intersectionImage = ImageIO.read(imageUrl );
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (intersectionImage != null) {
g.drawImage(intersectionImage, 0, 0, this);
}
}
#Override
public Dimension getPreferredSize() {
if (intersectionImage != null) {
int width = intersectionImage.getWidth();
int height = intersectionImage.getHeight();
return new Dimension(width , height );
}
return super.getPreferredSize();
}
private static void createAndShowGui() {
IntersectionImagePanel mainPanel = new IntersectionImagePanel();
JFrame frame = new JFrame("IntersectionImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}