Swing - new ImageIcon from Color - java

I need to programmatically create an ImageIcon with a simple color (let's say blue):
So I started doing this :
ImageIcon imageIcon = new ImageIcon();
Now I am trying to fill my ImageIcon with a blue color.

This should do the trick
BufferedImage image = new BufferedImage(60, 60, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setPaint(new Color(0, 0, 128));
graphics.fillRect(0, 0, image.getWidth(), image.getHeight());
ImageIcon imageIcon = new ImageIcon(image);

Based on the answer Lonely Neuron, I created a method to create a new ImageIcon with the desired size and Color:
public static ImageIcon createImageIcon(Color color, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = image.createGraphics();
graphics.setPaint(color);
graphics.fillRect (0, 0, width, height);
return new ImageIcon(image);
}
Call it like so:
ImageIcon imageIcon = createImageIcon(new Color(0, 0, 128), 60, 60);

Here is an example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
public class CreateImage {
public static void main(String[] args) {
JFrame frm = new JFrame("Test");
frm.add(new JLabel(createImage(Color.BLUE, new Dimension(200, 100))));
frm.pack();
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public static Icon createImage(Color c, Dimension size) {
BufferedImage img = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.createGraphics();
g.setColor(c);
g.fillRect(0, 0, size.width, size.height);
return new ImageIcon(img);
}
}

Related

How can increase only image width in java

try
{
BufferedImage original = ImageIO.read(OriginalImage);
BufferedImage resized = new BufferedImage(width, null, original.getType());
Graphics2D g2 = resized.createGraphics();
g2.drawImage(original, 0, 0, width, null, null);
g2.dispose();
ImageIO.write(resized, format, resizedImage);
}
I want to increase image width only height automatic adjust by width pixel.
Use the method Image.getScaledInstance as it show in the example below
import java.awt.BorderLayout;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class ImageTest {
private static final int WIDTH_INCREMENT = 100;
public static void main(String[] args) throws Exception {
BufferedImage image = ImageIO.read(new File("D:\\DDownloads\\Download.png"));
int targetWidth = image.getWidth() + WIDTH_INCREMENT;
// compute height using the aspect ratio
int targetHeight = (int) ((double) targetWidth * image.getHeight()) / image.getWidth();
Image target = image.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
// also you can use -1 as new height
// image.getScaledInstance(targetWidth, -1, Image.SCALE_SMOOTH);
// in this case the method computes the correct width by himself
BufferedImage toWrite = new BufferedImage(
targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = toWrite.createGraphics();
g2.drawImage(target, 0, 0, targetWidth, targetHeight, null);
g2.dispose();
ImageIO.write(toWrite, "png", new File("D:\\\\DDownloads\\\\converted.png"));
// next code is to show the both original and converted image on the screen
// Use invokeLater ofr correct initialization of Swing components
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frm = new JFrame("Images");
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.add(new JLabel(new ImageIcon(image)), BorderLayout.NORTH);
frm.add(new JLabel(new ImageIcon(target)), BorderLayout.SOUTH);
frm.pack();
frm.setLocationRelativeTo(null); // center the window
frm.setVisible(true);
}
});
}
}

How to put user defined text on image?

I would like to get user defined text on image, like if I'll make two text fields, one is for name and second for date so when I input someone's name and date, after inputting if I clicked OK then it'll display in that image.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class billFrame extends JFrame
{
public billFrame()
{
JFrame f1 = new JFrame("Billng Application");
f1.setDefaultCloseOperation(EXIT_ON_CLOSE);
f1.setSize(500,500);
f1.setBounds(30, 50, 500, 700);
f1.setExtendedState(JFrame.MAXIMIZED_BOTH);
ImageIcon icon = new
ImageIcon("C:\\Users\\Dhaval\\Downloads\\shrihari.png");
Image image = icon.getImage();
JPanel panel1;
panel1 = new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 1400, 0, 500, 700, this);
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(320, 200);
}
};
f1.add(panel1);
panel1.setVisible(true);
panel1.setLayout(null);
JLabel name = new JLabel("Name :");
name.setVisible(true);
name.setLocation(100,100);
name.setSize(100,100);
panel1.add(name);
JTextField namet = new JTextField();
namet.setVisible(true);
namet.setLocation(150, 137);
namet.setSize(200,30);
panel1.add(namet);
f1.setVisible(true);
}
#SuppressWarnings("unchecked")
public static void main(String args[])
{
billFrame bf = new billFrame();
}
}
Here is sample:
static void addTextWatermark(String text, File sourceImageFile, File destImageFile) {
try {
BufferedImage sourceImage = ImageIO.read(sourceImageFile);
Graphics2D g2d = (Graphics2D) sourceImage.getGraphics();
// initializes necessary graphic properties
AlphaComposite alphaChannel = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f);
g2d.setComposite(alphaChannel);
g2d.setColor(Color.BLUE);
g2d.setFont(new Font("Arial", Font.BOLD, 64));
FontMetrics fontMetrics = g2d.getFontMetrics();
Rectangle2D rect = fontMetrics.getStringBounds(text, g2d);
// calculates the coordinate where the String is painted
int centerX = (sourceImage.getWidth() - (int) rect.getWidth()) / 2;
int centerY = sourceImage.getHeight() / 2;
// paints the textual watermark
g2d.drawString(text, centerX, centerY);
ImageIO.write(sourceImage, "png", destImageFile);
g2d.dispose();
System.out.println("The tex watermark is added to the image.");
} catch (IOException ex) {
System.err.println(ex);
}
}
And here is usage
File sourceImageFile = new File("name.png");
File destImageFile = new File("anothername.png");
addTextWatermark("Text", sourceImageFile, destImageFile);
Or you can us libs for that. For example: http://www.gif4j.com

Why is my image not filled with green?

i've seen a similar question, but i didn't get a proper solution, so here's my problem:
(Coloring an area of BufferedImage)
i'm creating a BufferedImage, then i grab the graphics from this image, i'll paint a green rectangle on it and let it show within a JPanel... but surprise - it's not green, wo where is my error??
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ViewPortTest {
public static void main(String[] args) {
new ViewPortTest().startUp();
}
private void startUp() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(new TestPanel() );
frame.pack();
frame.setVisible(true);
}
private class TestPanel extends JPanel{
private static final long serialVersionUID = 1L;
private int myWidth = 256;
private int myHeight = 156;
private BufferedImage img;
public TestPanel() {
super();
setPreferredSize(new Dimension(myWidth, myHeight) );
img = new BufferedImage(myWidth, myHeight, BufferedImage.TYPE_4BYTE_ABGR);
img.createGraphics();
img.getGraphics().setColor(Color.GREEN);
img.getGraphics().fillRect(0, 0, 256, 256);
img.getGraphics().dispose();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null ){
g.drawImage(img, 0, 0, null);
}
}
}
}
what comes out is this:
so - where is my green rectangle???
The problem is the multiple calls to getGraphics(). It is creating multiple Graphics objects. This is essentially an alias for createGraphics(). See BufferedImage#getGraphics. A simple fix would be to store the Graphics2D object created by calling createGraphics() and make all of your calls on that object:
Graphics2D g = img.createGraphics();
g.setColor(Color.GREEN);
g.fillRect(0, 0, 256, 256);
g.dispose();
Because createGraphics() always returns a new Graphics2D context. So you set the green color on one context, and you fill a rectange using another which does not know about the green color you set on another context.
Try this:
Graphics2d g = img.createGraphics();
g.setColor(Color.GREEN);
g.fillRect(0, 0, 256, 256);
g.dispose();
Simple problem with Graphics instance:
Graphics2D createGraphics = img.createGraphics();
createGraphics.setColor(Color.GREEN);
createGraphics.fillRect(0, 0, 256, 256);
createGraphics.dispose();

Colors appear wrong in image file if image type is TYPE_INT_ARGB and writing with ImageIO

The code below creates apparently wrong image file.
It appears as
while it should be
or something. Anyway, circle should be yellow.
How to fix?
The code is below
package tests.org.piccolo2d;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
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;
import org.piccolo2d.nodes.PPath;
public class Try_SaveImage {
public static void main(String[] args) throws IOException {
/*
PPath path = PPath.createEllipse(0, 0, 100, 100);
path.setPaint(new Color(0xECB77E));
path.setStrokePaint(Color.black);
BufferedImage image = (BufferedImage) path.toImage();
*/
//BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); // works good
BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB); // works bad
Graphics2D g2 = (Graphics2D) image.getGraphics();
g2.setColor(Color.yellow);
g2.fillOval(0, 0, 100, 100);
g2.setColor(Color.black);
g2.drawOval(0, 0, 100, 100);
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new JLabel(new ImageIcon(image)), BorderLayout.CENTER);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
ImageIO.write(image, "JPG", new File("testdata/circle.jpg"));
}
}
I had pretty much the same problem. Unexpected colors. Doing as haraldK suggests above fixed the issue for me. Use TYPE_INT_RGB not TYPE_INT_ARGB.
This produced the expected black line on a white background whereas using TYPE_INT_ARGB did not
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setPaint(Color.WHITE);
g2d.fillRect(0, 0, 200, 200);
g2d.setPaint(Color.BLACK);
g2d.drawLine(0, 0, 200, 200);
ImageIO.write(bi, "JPEG", new File("c:\\temp\\TestImage.JPG"));
It seems that it is a know bug in ImageIO
have a look at [ jpeg image color gets drastically changed after just ImageIO.read() and ImageIO.write() ]

How to disable java.awt.Graphics.fillRect(int x, int y, int width, int height)'s effect?

It's the original image:
I use java.awt.Graphics.fillRect(int x, int y, int width, int height) to add a coloured rectangle on the image.
Graphics imageGraphics = image.createGraphics();
Color color = new Color(0,0,0,100);
imageGraphics.setColor(color);
imageGraphics.fillRect(0, 0, 800, 600);
So the image has been inverted and looks like this:
After that,I want to clear the black transparent rectangle partly and show the original image.
imageGraphics.clearRect(100,100,100,100);
But the effect is like this:
What my requirement is:
I want to know why it doesn't work and is there any other way to realize it?
Remember, painting is destructive. It might be possible to use AlphaComposite to achieve this result, but a simpler solution might be to simple constructive a compound shape and paint that instead.
The following example creates two Rectangles, one been the area we want to fill and one been the area we want to show, the second is then subtracted from the first (to create the window) and then the result is painted on top of the image
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowArea {
public static void main(String[] args) {
new ShowArea();
}
public ShowArea() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
public TestPane() {
try {
img = ImageIO.read(new File("sample.png"));
Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight());
Rectangle clip = new Rectangle(150, 10, 100, 100);
Area area = new Area(bounds);
area.subtract(new Area(clip));
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.BLACK);
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fill(area);
g2d.dispose();
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}
If I were doing some kind of paint program, I would do this all within the paintComponent method or in some way that it didn't effect the original image, otherwise you've basic destroyed the image until you re-load it
Another solution might be to take a copy of the original area you want to keep and repaint it back on top after, for example...
img = ImageIO.read(new File("sample.png"));
// This is the portion of the image we want to save...
BufferedImage cutout = img.getSubimage(150, 10, 100, 100);
// This is the area we want to paint over...
Rectangle bounds = new Rectangle(0, 0, img.getWidth(), img.getHeight());
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.BLACK);
// Save the current Composite so we can reset it...
Composite comp = g2d.getComposite();
// Apply the composite and fill the area...
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fill(area);
// Reset the composite
g2d.setComposite(comp);
// Draw the part of the image we saved previously...
g2d.drawImage(cutout, 150, 10, this);
g2d.dispose();
You cant do that the way you're trying to.
It can be done by creating a BufferedImage filled with Color(0,0,0,200), then in that image draw rectangle with color Color(0,0,0,200) and then apply it on image.
Remember, that drawing filledRectange is not a "undo operation"- it is written on pixels and it can't be undone.
EDIT
Icon imageIcon = new javax.swing.ImageIcon("image.jpg");
BufferedImage mask = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
BufferedImage image = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR);
imageIcon.paintIcon(null, image.getGraphics(), 0, 0);
Graphics maskGraphics = mask.getGraphics();
//drawing grey background
maskGraphics.setColor(new Color(0, 0, 0, 120));
maskGraphics.fillRect(0, 0, mask.getWidth(), mask.getHeight());
//drawing black frame
maskGraphics.setColor(new Color(0, 0, 0, 255));
maskGraphics.drawRect(99, 99, 301, 301);
//drawing original image window
maskGraphics.drawImage(image, 100, 100, 400, 400, 100, 100, 400, 400, null);
//apply mask on image
new ImageIcon(mask).paintIcon(null, image.getGraphics(), 0, 0);
//result presentation
label.setIcon(new ImageIcon(image));
Yes this is easily doable. The problem is that any draw operation is destructive, what you see is what you get, the information that was painted upon is lost.
Something like this where you store a subimage, do your paint operation then draw the subimage back on top.
public class Q23709070 {
public static void main(String[] args) {
JFrame frame = new JFrame();
Panel p = new Panel();
frame.getContentPane().add(p);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
static class Panel extends JPanel {
int w = 400;
int h = 400;
int x = 100;
int y = 100;
BufferedImage img;
BufferedImage subImg;
BufferedImage save;
public Panel() {
try {
img = ImageIO.read(getClass().getResourceAsStream("0qzCf.jpg"));
} catch (IOException e) {
}
subImg = img.getSubimage(x, y, w, h);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color g2dColor = g2d.getColor();
Color fillColor = new Color(0, 0, 0, 100);
g2d.drawImage(img, 0, 0, null);
g2d.setColor(fillColor);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.drawImage(subImg, x, y, null);
g2d.setColor(g2dColor);
if (save == null) {
save = new BufferedImage(img.getWidth(), img.getHeight(),
img.getType());
this.paint(save.getGraphics());
try {
ImageIO.write(save, "jpg", new File("save.jpg"));
} catch (IOException e) {
}
}
}
#Override
#Transient
public Dimension getPreferredSize() {
return new Dimension(img.getWidth(), img.getHeight());
}
}
}
Rendering

Categories