Darkening image using Graphics2D issue in Windows 7 64-bit - java

My small Java program is trying to darken a png image. It's working fine on my Mac but when I try to run it on a Windows PC with java 1.7_07 installed but it doesn't show anything at all except an empty JPanel, the image is completely disappeared.
Here is the code:
class MapCanvas extends JPanel {
private Color color;
RescaleOp op;
BufferedImage sourceImage, bi;
public MapCanvas() {
try {
sourceImage = ImageIO.read(new File(MAP_FILENAME));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
op = new RescaleOp(.8f, 0, null);
bi = op.filter(bi, null);
Graphics2D g = bi.createGraphics();
g.drawImage(sourceImage, 0, 0, 500, 382, null);
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
// set size for the panel
Dimension size = new Dimension(500, 382);
this.setBackground(new Color(34, 102, 187));
setPreferredSize(size);
setSize(size);
setLayout(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(bi, op, 0, 0);
}
}
Anyone know why I'm getting this? Many thanks.

I don't seem to have any issues, BUT, several things jump out at me about this example...
Firstly, I don't see why you've done this...
try {
sourceImage = ImageIO.read(new File("C:/Users/shane/Dropbox/issue453.jpg"));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
op = new RescaleOp(.1f, 0, null);
bi = op.filter(bi, null);
Graphics2D g = bi.createGraphics();
g.drawImage(sourceImage, 0, 0, 500, 382, null);
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
Then done this...
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(bi, op, 0, 0);
}
You're basically double apply the RescaleOp.
It could simply just apply the RescaleOp directly to the sourceImage...
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(sourceImage, op, 0, 0);
}
Unless you're concerned about performance, in which case you should simple draw the bi without any BufferedImageOp
g2d.drawImage(bi, 0, 0, this);
Secondly, your example won't compile because you've not defined g2d in your paintComponent method. This is either an oversight (which is fine) OR you are caching the Graphics object, which is not fine.
Graphics objects are stateless, they do not persist between repaints, you should NEVER cache them or rely on getGraphics.

Thank you for pointing out my mistakes. There is some missing code in my question (the Graphics2D g2d - it's just an unassigned variable) so it doesn't compile. Sorry about that.
This is how I fixed it:
`sourceImage = ImageIO.read(new File(MAP_FILENAME));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
float[] scales = { .5f, .5f, .5f, 1f };
float[] offsets = new float[4];
op = new RescaleOp(scales, offsets, null);
Graphics2D g1 = bi.createGraphics();
g1.drawImage(sourceImage, 0, 0, 500, 382, null);
g1.dispose();
op.filter(sourceImage, bi);`
I just use the same value for RGB in the scales array (that's how it supposed to be) then draw the filtered image.
`g2d.drawImage(bi, 0, 0, 500, 382, null);`
Cheers

Related

How do I create a kaleidoscopic photo with this?

For my assignment I need to turn this singular picture.
Into this:
I've tried using negatives and reversing it manually but that didn't work out.
DrawingImages.java
```java
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
public class DrawingImages
{
private Picture newCanvas = null;
private Graphics g = null;
private Graphics2D g2 = null;
private Picture pic1 = null;
private Color color = null;
int height= 250;
int width = 250;
DrawingImages(Picture canv, Picture p1)
{
newCanvas = canv;
newCanvas.setAllPixelsToAColor(Color.BLACK);
g = newCanvas.getGraphics();
g2 = (Graphics2D)g;
pic1 = p1;
}
public Picture drawPicture()
{
//Flip the image both horizontally and vertically
g2.drawImage(image, x+(width/2), y+(height/2), -width, -height, null);
//Flip the image horizontally
g2.drawImage(image, x+(width/2), y-(height/2), -width, height, null);
//Flip the image vertically
g2.drawImage(image, x-(width/2), y+(height/2), width, -height, null);
return newCanvas;
}
}
```
DrawingImagesTester.java
```java
import java.awt.Color;
public class DrawImagesTester
{
public static void main(String[] args)
{
Picture canvas = new Picture(500, 500);
Picture picture1 = new Picture("flower1.jpg");
DrawingImages draw = new DrawingImages(canvas, picture1, Color.YELLOW);
canvas = draw.drawPicture();
canvas.show();
}
}
You need to mirror the image. The process is actually really simple and is a commonly used trick. You simply need to scale the image in a negative direction, along the axis you want mirrored (and then translate the image so it will re-appear within the user space)
For example...
BufferedImage img = ImageIO.read(new File("/Users/shanew/Downloads/kAJZbDc.jpg"));
BufferedImage mirrored = new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
Graphics2D g2d = mirrored.createGraphics();
g2d.scale(-1, 1);
g2d.translate(-mirrored.getWidth(), 0);
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
BufferedImage combined = new BufferedImage(img.getWidth() * 2, img.getHeight(), img.getType());
g2d = combined.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.drawImage(mirrored, img.getWidth(), 0, null);
g2d.dispose();
JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(combined)));

How can I fix this NullPointerException when trying to render on a JPanel with Graphics2D? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I've been trying to make a shop for my game.
This has been unsuccessful.
I've tried drawComponent, didn't work.
No errors, code executed, but didn't work.
Now i'm trying to do:
private void render() {
Graphics2D g = (Graphics2D) graphics.getGraphics();
/////////////////////
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
/////////////////////
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
}
Now i get a NullPointerException on g2d.
I've tried everything.
`Exception in thread "game" java.lang.NullPointerException
at com.johnythecarrot.game.Shop$DrawPane.access$2(Shop.java:123)
at com.johnythecarrot.game.Shop.render(Shop.java:154)
at com.johnythecarrot.game.Game.render(Game.java:75)
at com.johnythecarrot.game.Game.run(Game.java:112)
at java.lang.Thread.run(Unknown Source)`
My goals are to be able to have clickable buttons.
It DID work. But i had to restart almost everytime. Because mostly of the time to code wasn't even executed. So i tried to fix it. Now it's all messed up.
This is the code to it.
(DoubleInt is a part of my library it's nothing more than just x and y. )
public class Shop {
public BuildWindow window;
public static JWindow w;
private int WIDTH = 860, HEIGHT = 440;
private BufferedImage graphics = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
public DrawPane drawPane;
public Shop() {
//window = new BuildWindow().setSize(new DoubleInt(100, 100)).at(wi, he).setTitle("Shop").setOpacity(1).setDragable(false).showEmpty(true);
w = new JWindow();
w.setOpacity(1);
w.setSize(WIDTH, HEIGHT);
w.setLocation(800, 800);
w.setVisible(false);
w.setAlwaysOnTop(true);
//graphics = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
}
private void createShop() {
/***Graphics2D g = (Graphics2D) graphics.getGraphics();
g.setColor(Color.blue);
g.drawString("hey", WIDTH-50, HEIGHT-50);
g.fillRect(0, 0, WIDTH, HEIGHT);*/
}
public class DrawPane extends JPanel {
int width = WIDTH;
int height = HEIGHT;
private ArrayList<Shape> buttons;
private Shape btn1 = new Rectangle2D.Double(20, 60, width/2, height-20);
private Shape btnClose = new Rectangle2D.Double(width-25, 5, 20, 20);
Point wCoords;
Point mCoords;
public DrawPane() {
buttons = new ArrayList<>();
buttons.add(btn1);
buttons.add(btnClose);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
for(Shape s : buttons) {
if(s.contains(e.getPoint())) {
System.out.println("Clicked " + s.getBounds());
if(s == btnClose) {
w.dispose();
}
}
}
}
#Override
public void mousePressed(MouseEvent e) {
mCoords = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
mCoords = null;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
wCoords = e.getLocationOnScreen();
w.setLocation(wCoords.x - mCoords.x, wCoords.y - mCoords.y);
}
});
}
void repaintThis() {
repaint();
}
BufferedImage img = loadImageFrom.LoadImageFrom(Shop.class, "bar.png");
Graphics gb;
/**
* super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.red);
//g.fillRect(0, 0, width, 50);
g.drawImage(img, 0, 0, width, 50, null);
g.setColor(Color.WHITE);
g.drawString("SHOP", 15, 30);
g.drawString("X", width-20, 20);
for(Shape b : buttons) {
g2d.draw(b);
}
System.out.println("Built");
gb = g;
*/
private void render() {
Graphics2D g = (Graphics2D) graphics.getGraphics();
/////////////////////
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
/////////////////////
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
}
public void Build() {
Graphics g = gb;
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.red);
//g.fillRect(0, 0, width, 50);
g.drawImage(img, 0, 0, width, 50, null);
g.setColor(Color.WHITE);
g.drawString("SHOP", 15, 30);
g.drawString("X", width-20, 20);
for(Shape b : buttons) {
g2d.draw(b);
}
System.out.println("Built");
}
}
public void render(Graphics2D g) {
drawPane.render();
}
public void addDrawPane() {
drawPane = new DrawPane();
w.add(drawPane);
}
}
If you need access to more code, just ask me.
You should override the paintComponent method like this:
public class DrawPane extends JPanel {
// all your variables and other things
#Override
paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
// Your code goes here, use the g2d
}
}
then if you need to repaint your component, simply call repaint() on it.

Rounded Image in a java swing Jlabel

I have been banging my head since morning on a a Jlabel issue; I would like to have an round image instead of the normal rectangular image for a label as shown in the image below.
I have tried overriding paintComponent in the label but the image would not display at all. I have not found a very concrete answer on previous SO posts. Your help is welcome. Thanks in advance.
My code is as below:
jLabelPic = new javax.swing.JLabel(){
BufferedImage image= null;
private Ellipse2D.Double border = new Ellipse2D.Double();
private int width=140, height=140;
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
try {
image= ImageIO.read(getClass().getResource("/resources/image.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.RED);
g2d.fillRect(0, 0, width, height);
border.setFrame(0, 0, width, height);
g2d.setClip(border);
g2d.drawImage(image, 0, 0, width, height, this);
}
};

Where do I put images for java program to input?

I've been following a tutorial to learn graphics and in one program the author uses images to make texture paints. I have copied his code however I dont know where to actually put the images for it to read. I have tried making a resources folder in eclipse and setting it as a source folder build path but this didnt work. The code is below:
EDIT:
Okay, I figured out that it is taking images from the source of the class. However, lets say I wanted to pull an image from my desktop, or some other location on my hard drive, how would i do this?
class Surface extends JPanel {
private BufferedImage slate;
private BufferedImage java;
private BufferedImage pane;
private TexturePaint slatetp;
private TexturePaint javatp;
private TexturePaint panetp;
public Surface() {
loadImages();
}
private void loadImages() {
try {
slate = ImageIO.read(new File("slate.png"));
java = ImageIO.read(new File("java.png"));
pane = ImageIO.read(new File("pane.png"));
} catch (IOException ex) {
Logger.getLogger(Surface.class.getName()).log(
Level.SEVERE, null, ex);
}
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
slatetp = new TexturePaint(slate, new Rectangle(0, 0, 90, 60));
javatp = new TexturePaint(java, new Rectangle(0, 0, 90, 60));
panetp = new TexturePaint(pane, new Rectangle(0, 0, 90, 60));
g2d.setPaint(slatetp);
g2d.fillRect(10, 15, 90, 60);
g2d.setPaint(javatp);
g2d.fillRect(130, 15, 90, 60);
g2d.setPaint(panetp);
g2d.fillRect(250, 15, 90, 60);
g2d.dispose();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
This can be helpful. Or just use absolute PATH to file. linux: /home/user/... widndows: C:/Users/..

Java 3 Color Gradient

I have a JPanel, and I would like to paint a gradient within it. I have the code below, but that only paints a 2 color gradient. I would like to add a 3rd but don't know how. What I want is to have the top left of the panel as white, top right red, and both bottom corners black. What would I have to do to achieve this, something that looks like this:
package pocketshop.util;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class ColorPicker extends JPanel{
public ColorPicker(){
repaint();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
int w = getWidth();
int h = getHeight();
GradientPaint gp = new GradientPaint(
0, 0, Color.white,
0, h, Color.black);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
}
}
Edit: Possible solution
I was able to come up with using 2 gradients one horizontal and one vertical, like this:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
int w = getWidth();
int h = getHeight();
// Vertical
GradientPaint gp = new GradientPaint(
0, 0, new Color(0,0,0,0),
0, h, Color.black);
// Horizontal
GradientPaint gp2 = new GradientPaint(
0, 0, Color.white,
w, 0, Color.red, true);
g2d.setPaint(gp2);
g2d.fillRect(0, 0, w, h);
g2d.setPaint(gp);
g2d.fillRect(0, 0, w, h);
}
Something like this?
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ThreeWayGradient {
public static void main(String[] args) {
final BufferedImage image = new BufferedImage(
200, 200, BufferedImage.TYPE_INT_RGB);
Runnable r = new Runnable() {
#Override
public void run() {
Graphics2D g = image.createGraphics();
GradientPaint primary = new GradientPaint(
0f, 0f, Color.WHITE, 200f, 0f, Color.ORANGE);
GradientPaint shade = new GradientPaint(
0f, 0f, new Color(0, 0, 0, 0),
0f, 200f, new Color(0, 0, 0, 255));
g.setPaint(primary);
g.fillRect(0, 0, 200, 200);
g.setPaint(shade);
g.fillRect(0, 0, 200, 200);
JLabel l = new JLabel(new ImageIcon(image));
JOptionPane.showMessageDialog(null, l);
File f = new File(System.getProperty("user.home"),
"ThreeWayGradient.png");
try {
ImageIO.write(image, "png", f);
} catch (IOException ex) {
ex.printStackTrace();
}
}
};
SwingUtilities.invokeLater(r);
}
}
Making it into a factory method
..because it is prettier.
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class ThreeWayGradient {
public static BufferedImage getThreeWayGradient(
int size,
Color primaryLeft,
Color primaryRight,
Color shadeColor) {
BufferedImage image = new BufferedImage(
size, size, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
GradientPaint primary = new GradientPaint(
0f, 0f, primaryLeft, size, 0f, primaryRight);
int rC = shadeColor.getRed();
int gC = shadeColor.getGreen();
int bC = shadeColor.getBlue();
GradientPaint shade = new GradientPaint(
0f, 0f, new Color(rC, gC, bC, 0),
0f, size, shadeColor);
g.setPaint(primary);
g.fillRect(0, 0, size, size);
g.setPaint(shade);
g.fillRect(0, 0, size, size);
g.dispose();
return image;
}
/**
* Presumed to have a layout that shows multiple components.
*/
public static void addGradient(
JPanel p, int s, Color pL, Color pR, Color sh) {
JLabel l = new JLabel(new ImageIcon(getThreeWayGradient(s, pL, pR, sh)));
p.add(l);
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new GridLayout(2,4,1,1));
addGradient(gui,100,Color.YELLOW,Color.RED,Color.GREEN);
addGradient(gui,100,Color.GREEN,Color.YELLOW,Color.RED);
addGradient(gui,100,Color.RED,Color.GREEN,Color.YELLOW);
addGradient(gui,100,Color.BLUE,Color.MAGENTA,Color.PINK);
addGradient(gui,100,Color.WHITE,Color.RED,Color.BLACK);
addGradient(gui,100,Color.RED,Color.GREEN,Color.BLACK);
addGradient(gui,100,Color.BLUE,Color.PINK,Color.BLACK);
addGradient(gui,100,Color.BLUE,Color.CYAN,Color.BLACK);
JOptionPane.showMessageDialog(null, gui);
}
};
SwingUtilities.invokeLater(r);
}
}
Take a look at LinearGradientPaint, it allows you to specify n number of colours and their weights.
Update 1
With a "small" change in requirements, it is debatable if either LinearGradientPaint over GradientPant will have any significant effect in performance.
I highly recommend that you take a look at Harmonic Code. This guy does some really interesting posts, and some on gradients. ;)
Update 2
Knew I'd seen something like it before Bilinear color interpolation.

Categories