I'm working on an application which allows a used to place controls, move, resize, etc. But I'm trying to add icon images to a button control. When placed and instanced, it resizes the icon image per the code below.
But when I resize the control using user features and it calls this routing again, it fails to resize the image and it remains the original icon size. I've tried using "this.", passing the control to itself, I've done prints to ensure it's seeing the new size and width... what I am missing?
Also, when I create a 2nd control (or 3rd, etc), it uses the 1st image's initial size.
Thanks!
protected void sizeIcon () {
try {
File f2 = new File("media\\button.gif");
BufferedImage inputImage = ImageIO.read(f2);
BufferedImage img = new BufferedImage(this.getWidth(), this.getHeight(), inputImage.getType());
Graphics2D g = img.createGraphics();
g.drawImage(inputImage, 7, 0, this.getWidth(), this.getHeight(), null);
ImageIO.write(img, "gif", new File("test.gif"));
this.setIcon(new ImageIcon("test.gif"));
g.dispose();
} catch(Exception e) {System.out.println(e);}
Sorry, got it, appears the old file was not being replaces.
-MH
Related
I need a function/method that can mold(crop and resize) an imported (.png format) image into a circle of exact 150x150 pixels and it should keep transparency. I have searched all over internet, also I have my own code but I think its completely useless. I need this function for a code I am using to make GUI of a social-media app database.
private ImageIcon logo = new ImageIcon(getClass().getResource("/test/test200x200.png"));
toCircle(logo);
I need the code for the following function:
public ImageIcon toCircle(ImageIcon icon)
{
//code
return icon;
}
This function should convert this picture:
To this:
Create a new transparent image
Get a Graphics object from the image.
Set a clip for the graphics object.
Paint the PNG format image.
See also this answer that uses a clipped region.
An alternative approach, that might be more straight-forward to implement for this use case, is:
Create a transparent BufferedImage the size of your icon
Create Graphics2D from image, set hints for antialias
Fill a circle the size of your background circle
Draw the image on top of your circle, using AlphaComposite.SrcIn
Something like:
public Icon toCircle(ImageIcon logo) {
BufferedImage image = new BufferedImage(150, 150); // Assuming logo 150x150
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.fillOval(1, 1, 148, 148); // Leaving some room for antialiasing if needed
g.setComposite(AlphaComposite.SrcIn);
g.drawImage(logo.getImage(), 0, 0, null);
g.dispose();
return new ImageIcon(image);
}
I use OpenImaj for a project and I need to display the video in 800*600 to a panel but I must capture images at 1920,1080 when I click a button.
My strategy was initially to capture from my webcam at 1920,1080 and to resize image in a icon of a label contained in my panelVideo.
My problem is that the performance is very low.
Is there an efficient method to resize video according to the size of panelVideo without changing the frame size (that I use for saving the image at 1920,1080)?
Thank you for your answer.
Regards.
final VideoCapture vc = new VideoCapture(1920,1080);
vc.setFPS(10);
final VideoDisplay<MBFImage> display = VideoDisplay.createVideoDisplay(vc, panelVideo);
display.addVideoListener(new VideoDisplayAdapter<MBFImage>()
{
#Override
public void beforeUpdate(final MBFImage frame)
{
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
g.drawImage(ImageUtilities.createBufferedImageForDisplay(frame), 0, 0, 800, 600, null);
//here is the label that I use to display the video
labelVideo.setIcon(new ImageIcon(ImageUtilities.createBufferedImageForDisplay(frame)));
}
});
You can at least remove fixed code like this out of the loop - that is create it only once
//here I create a bufferedImage from the resized frame
BufferedImage img = new BufferedImage(800, 600, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) img.getGraphics();
and also have the Icon created once and setImage() as needed. Beyond that I dont know how to convert MBF to BufferedImage thats the pain of using different libraries. g.drawImage() is a good way to draw the scaled image.
See http://openimaj.org/apidocs/org/openimaj/image/processing/resize/package-frame.html for the OpenIMAJ classes that let you resize an MBFImage. You'll have to play and see what is fastest, but in my very quick experiments I found BilinearInterpolation to be better than ResizeProcessor with the default options, however using a different filter in ResizeProcessor might be faster.
Rather than creating a new BufferedImage each frame, you would probably be better off drawing the MBFImage into a Swing component that displays them directly: http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ScalingImageComponent.html or http://openimaj.org/apidocs/org/openimaj/image/DisplayUtilities.ImageComponent.html (note that technically these both convert to BufferedImage behind the scenes, but they only allocate the image once and just redraw into it saving a lot of time).
So I have an assignment where I need to create a catalog.
The catalog needs to have a list, an image and a description.
My entire code works, so I have no issue with the coding as such.
I do have an issue with the image size.
How do I take care of images on a java gui program to make them all into one size when it is running.
Please let me know :D
When you read in an image, create a new BufferedImage that is the exact size that you desire, get it's Graphics object via getGraphics(), draw the original image into the new image using Graphics#drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) where x and y are 0 and width and height are from the dimensions of the new image, dispose() of the Graphics object, and then display the new Image as an ImageIcon in a JLabel. Make sure though that the original image is the same size or larger than the new one, else your images will look gawd-awful.
For example, and note that this code may not be exactly correct since I don't have my IDE up:
BufferedImage originalImage = ImageIO.read(something); // read in original image
// create new empty image of desired size
BufferedImage newImage = new BufferedImage(desiredWidth, desiredHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = newImage.getGraphics(); // get its graphics object
// draw old image into new image
g.drawImage(originalImage, 0, 0, desiredWidth, desiredHeight, null);
g.dispose(); // get rid of Graphics object
// create ImageIcon and put in JLabel to display
Icon newIcon = new ImageIcon(newImage);
myJLabel.setIcon(newIcon);
I would propably create a JPanel to draw on one Image, and then work with the method:
myPanel.setSize(new Dimension(x,y))
or
myPanel.setPreferredSize(new Dimension....)
There is a method (image = imgobj.getScaledInstance(width, height, hints)) in awt.Image class which provides re-sizing capabilities very nicely, I always use this to re-size my images when I need. Please see here some examples :-), I hope it will work for you, it is the most convenient way to scale images I have ever seen. create a method pass the image to the method and size of the image you want and return the image back in return to reuse the code ;)
I've setup a method for loading an image into a ByteBuffer and called Display.setIcon(), this works... partially. This sets the icon of the taskbar, but leaves the window's icon as the default LWJGL icon. Is there another Display method I need to call? Or is this something to do with windows.
Here's the method of loading the icon if needed:
public static final ByteBuffer[] getIcon()
{
Image image = Toolkit.getDefaultToolkit().getImage("rw_icon.PNG");
MediaTracker tracker = new MediaTracker(new JPanel());
tracker.addImage(image, 0);
try
{
tracker.waitForAll();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
tracker.removeImage(image);
BufferedImage bufImage = new BufferedImage(32, 32, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D graphics = bufImage.createGraphics();
graphics.drawImage(image, 0, 0, null);
graphics.dispose();
image.flush();
ByteBuffer buffer = ByteBuffer.allocateDirect(32*32*4);
buffer.clear();
byte[] bufferData = (byte[])bufImage.getRaster().getDataElements(0, 0, 32, 32, null);
buffer.put(bufferData);
buffer.rewind();
return (new ByteBuffer[] {buffer});
}
No.
You just need to pass an array of two versions of the icon (16x16, 32x32) to the setIcon(..) method.
It seems like you misunderstood the ByteBuffer[]. You are supposed to pass an array of different ByteBuffers. Not just a ByteBuffer array with one element in it. Therefore it would probably be best to create a new method which basically just does what your getIcon() method does, but expects a String as a file path. That way you can easily create the real array of icon byte-buffers.
public static int setIcon(java.nio.ByteBuffer[] icons)
Sets one or more icons for the Display. On Windows you should supply at least one
16x16 icon and one 32x32. Linux (and similar platforms) expect one
32x32 icon. Mac OS X should be supplied one 128x128 icon The
implementation will use the supplied ByteBuffers with image data in
RGBA (size must be a power of two) and perform any conversions
nescesarry for the specific platform.
NOTE: The display will make a
deep copy of the supplied byte buffer array, for the purpose of
recreating the icons when you go back and forth fullscreen mode. You
therefore only need to set the icon once per instance.
http://lwjgl.org/javadoc/org/lwjgl/opengl/Display.html#setIcon(java.nio.ByteBuffer[])
Have the following code:
image = new Image(display, imageData);
offScreenImageGC.drawImage(image, 0, 0, imageData.width, imageData.height, imageData.x, imageData.y, imageData.width, imageData.height);
/* Draw the off-screen image to the shell. */
shellGC.drawImage(offScreenImage, 0, 0);
... after executing the bottom instruction: shellGC.drawImage(offScreenImage, 0, 0); sometimes I get the image visible on the shellGC component, sometimes - not. I get it visible only when I "slow down" the execution of the program , for example when I am in debug mode. But when it runs fast - it does not show. I want it forcefully shown, flushed or whatever you name it, is it possible ?
Let me clarify that what I want to achieve is to implement an animation which is frame based, but yet to be able to play it double buffered, able to stop it, show only particular single frame paused, and etc things...
Thank you.
It came out that this is the ONLY SAFE way to double buffer with SWT:
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
//Obtain the next frame
ImageData imageData = imageDataArray[iad.imageNumber];
Image imageFrame = new Image(display, imageData);
// Create the image to fill the canvas
Image image = new Image(display, canvas.getBounds());
// Set up the offscreen gc
GC gcImage = new GC(image);
//Draw the image offscreen
gcImage.setBackground(event.gc.getBackground());
gcImage.drawImage(imageFrame, 0, 0);
// Draw the offscreen buffer to the screen
event.gc.drawImage(image, 0, 0);
imageFrame.dispose();
image.dispose();
gcImage.dispose();
}
});
.... by using this method ONLY for doublebuffering there is guaranteed crossplatform equal runtime behaviour, and the unpredictable buffer behaviour is also gone.