Creating images with a java - java

Hello) Help solve the problem:
We need to create a green square image and display it.
I could draw a square, but I need to create it using java.
Please help me to do this)
That's what I tried to do:
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
public class Game extends Canvas {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 400;
private static final int HEIGHT = 400;
#Override
public void paint(Graphics g) {
super.paint(g);
int w = 10;
int h = 10;
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage image = new BufferedImage(w, h, type);
int color = 257; // RGBA value, each component in a byte
for (int x = 1; x < w; x++) {
for (int y = 1; y < h; y++) {
image.setRGB(x, y, color);
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
frame.add(new Game());
frame.setVisible(true);
}
}
But nothing is displayed (
Let me remind the goal - to create a picture in the form of green squares, help to make it)

The simplest approach would be to simply use the graphics API...
#Override
public void paint(Graphics g) {
super.paint(g);
int w = 10;
int h = 10;
g.setColor(Color.GREEN);
g.fillRect(0, 0, width, height);
}
But something tells me this isn't what you want, but it does form the basics for what you need to achieve your result.
Start by making image a instance field...
private BufferedImage image;
Then you need to create the image...
int type = BufferedImage.TYPE_INT_ARGB;
image = new BufferedImage(w, h, type);
Graphics2D g2d = image.createGraphics();
g2d.setColor(Color.GREEN);
g2d.fillRect(0, 0, w, h);
g2d.dispoe();
Then in you paint method, you need to draw the image...
g.drawImage(image, x, y, this);
Take a look at the 2D Graphics trail for mor details

You must use Graphics.drawRect() and Graphics.fillRect():
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawRect%28int,%20int,%20int,%20int%29
http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#fillRect%28int,%20int,%20int,%20int%29

if you want to create an Image with rectangle containing it, first create the image, draw on it using it's graphics. I am writing code snippets for you:
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
This will produce an image with Blue rectangle.

Related

PaintComponent disrupting grid drawing

I'm new to Java as well as user interfaces, and I have a problem with Java Graphics. What I'm trying to achieve is drawing a grid on a JPanel, and then paint custom components into the grid.
Here is the class I want to draw the grid on (its base extends JPanel).
public class RectGridPanel extends GridPanel
{
List<Rectangle> rects;
public RectGridPanel(Simulator sim)
{
super(sim);
this.rects = new ArrayList<Rectangle>();
this.setLayout(new GridLayout(20,20));
for(int x = 1; x < 801; x += 40)
{
for(int y = 2; y < 801; y += 40)
{
Cell newCell = new RectCell(x, y, sim);
this.add(newCell);
}
}
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
for(int x = 1; x < 801; x += 40)
{
for(int y = 2; y < 801; y += 40)
{
Rectangle rect = new Rectangle(x, y, 40, 40);
g2.draw(rect);
rects.add(rect);
}
}
}
}
Here are the cells I want to draw inside the grid:
public class RectCell extends Cell
{
Rectangle shape;
public RectCell(int x, int y, Simulator sim)
{
super(x, y, sim);
shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
g2.fill(shape);
}
}
So the grid on its own draws out fine, but as soon as I try to create cells inside it it gets disrupted like that:
public class RectCell extends Cell
{
Rectangle shape;
public RectCell(int x, int y, Simulator sim)
{
super(x, y, sim);
shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaint(Color.BLACK);
g2.fill(shape);
}
}
The Graphics object that is passed to this paintComponent() function defines the screen space where the current RectCell can draw. The coordinate sysetem is relative to the upper left corner of the RectCell, so drawing the background should always start at x = 0 and y = 0 or some other meaningful value. The coordinates here are not relative to the parent component as you seem to assume.
Better yet, set the background color and let Swing take care of painting it rather than painting a rectangle yourself.
It is not clear what you try to achive.
What is the reason for RectCell? Why not paint the shapes direct in the RectGridPanel?
The nested loop in the paintComponent it not a good idea. Be aware that the paintComponent is called very often and every time you in crease the rects list with new objects. The former painted rectangles get lost (qraphicaly) and new rectangles with the same parameters are blowing the list.

How to use graphics2D from BufferedImage object, with "getGraphics()" method?

I'm trying to make a 2D game, but I can't figure out why my graphics from precedent frames are still there. The effect is when moving a rectangle on x with 1 pixel / frame, I get a long bar drawn on my screen.
In the class body I declared the objects beneath like that:
private int x, y;
private BufferedImage image;
private Graphics2D g;
This is how I'm initializing:
x = 10, y = 25;
image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_BGR);
g = (Graphics2D) image.getGraphics();
r = new Rectangle(x, y, 10, 10);
I have method where I draw graphics:
Graphics g2 = this.getGraphics();
g2.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.draw(r);
g2.dispose();
I also have a tick method where I move the rectangle:
x++;
The class extends Canvas and implements Runnable for the game loop and I use a JFrame object .
This is the result of 10x10 rectangle movement:
capture

How can I get my image to flip?

I'm having a problem getting an image to flip. My program is supposed to show the default image and the flipped image. I thought that if I could replace the (0,0) pixel of the flipped picture with the (width-1,height-1) of the original picture, it would work, but instead of getting the original image, I get this.
Here is my code:
import java.awt.Color;
public class Horizontal {
public static void main(String[] args)
{
Picture source = new Picture(args[0]);//name of picture.
Picture flip = new Picture(source.width(), source.height());//sets the width and height of source
for (int i =0; i < source.width(); i++)
{
int w = 1;
int sw = source.width()-w;
for (int j = 0; j < source.width(); j++)
{
int h=1;
int sh = source.height()-h;
Color SourceColor = source.get(sw,sh);// return the the color pixel of (sw,sh)
flip.set(i, j, SourceColor);//suppose to replace the (i,j) pixel of flip with source's (sw,sh) pixel
h++;
}
w++;
}
source.show();// shows the original image
flip.show(); // shows flipped version of image
}
}
Chceck this site. It has great info about basic image algorithms in java.
You can copy code for flipping an image.
http://www.javalobby.org/articles/ultimate-image/#9
Flipping horizontally:
public static BufferedImage horizontalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = new BufferedImage(w, h, img.getType());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, w, 0, 0, h, null);
g.dispose();
return dimg;
}
Flipping vertically:
public static BufferedImage verticalflip(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
BufferedImage dimg = dimg = new BufferedImage(w, h, img.getColorModel().getTransparency());
Graphics2D g = dimg.createGraphics();
g.drawImage(img, 0, 0, w, h, 0, h, w, 0, null);
g.dispose();
return dimg;
}

Painting pixels images in Java

Which method is the best way to create a pixel image with java.
Say, I want to create a pixel image with the dimensions 200x200 which are 40.000 pixels in total. How can I create a pixel from a random color and render it at a given position on a JFrame.
I tried to create a own component which just creates pixel but it seems that this is not very performant if I create such a pixel a 250.000 times with a for-loop and add each instance to a JPanels layout.
class Pixel extends JComponent {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getRandomColor());
g.fillRect(0, 0, 1, 1);
}
}
You do not need to create a class for this. Java already has the excellent BufferedImage class that does exactly what you need. Here is some pseudo-code:
int w = 10;
int h = 10;
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage image = new BufferedImage(w, h, type);
int color = 255; // RGBA value, each component in a byte
for(int x = 0; x < w; x++) {
for(int y = 0; y < h; y++) {
image.setRGB(x, y, color);
}
}
// Do something with image
The key here is the Canvas class. It is the standard Component that allows arbitrary draw operations. In order to use it, you must subclass the Canvas class and override the paint(Graphics g) method, then loop through each pixel and draw your random color. The following code should work:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
public class PixelCanvas extends Canvas {
private static final int WIDTH = 400;
private static final int HEIGHT = 400;
private static final Random random = new Random();
#Override
public void paint(Graphics g) {
super.paint(g);
for(int x = 0; x < WIDTH; x++) {
for(int y = 0; y < HEIGHT; y++) {
g.setColor(randomColor());
g.drawLine(x, y, x, y);
}
}
}
private Color randomColor() {
return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(WIDTH, HEIGHT);
frame.add(new PixelCanvas());
frame.setVisible(true);
}
}
The generated image looks like this:
You'll probably want to create a BufferedImage of the size you want, and use img.setRGB(x, y, getRandomColor()) to create a bunch of random pixels. Then you could render the whole image wherever you want it.

Rotating BufferedImage instances

I am having trouble getting a rotated BufferedImage to display. I think the rotation is working just fine, but I can't actually draw it to the screen. My code:
Class extends JPanel {
BufferedImage img;
int rotation = 0;
public void paintComponent(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
img2d = img.createGraphics();
img2d.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
g.drawImage(img, imgx, imgy, null);
this.repaint();
}
}
This is not working for me. I could not find any way to draw the rotated img2d onto g.
EDIT: I have multiple objects that are being drawn onto g, so I can't rotate that. I need to be able to rotate things individually.
Maybe you should try using AffineTransform like this:
AffineTransform transform = new AffineTransform();
transform.rotate(radians, bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);
AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
bufferedImage = op.filter(bufferedImage, null);
Hope this helps.
I would use Graphics2D.drawImage(image, affinetranform, imageobserver).
The code example below rotates and translates an image to the center of the component. This is a screenshot of the result:
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Test");
frame.add(new JComponent() {
BufferedImage image = ImageIO.read(
new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// create the transform, note that the transformations happen
// in reversed order (so check them backwards)
AffineTransform at = new AffineTransform();
// 4. translate it to the center of the component
at.translate(getWidth() / 2, getHeight() / 2);
// 3. do the actual rotation
at.rotate(Math.PI / 4);
// 2. just a scale because this image is big
at.scale(0.5, 0.5);
// 1. translate the object so that you rotate it around the
// center (easier :))
at.translate(-image.getWidth() / 2, -image.getHeight() / 2);
// draw the image
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image, at, null);
// continue drawing other stuff (non-transformed)
//...
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
You are rotating the graphics for drawing into your image, not the image. Thats why you see no effect. Apply the rotation to the graphics you are painting on and it will draw the image rotated:
public void paintComponent(Graphics g) {
g.clearRect(0, 0, getWidth(), getHeight());
g.rotate(Math.toRadians(rotation), img.getWidth() / 2, img.getHeight() / 2);
g.drawImage(img, imgx, imgy, null);
this.repaint();
}
This will probably not draw entirely what you expect, the rotation will revolve around the coordinate origin. For the image to be rotate around its center you need to apply a coordinate translation before the rotation, for example:
g.translate(imgx >> 1, imgy >> 1);
The Graphics2D Tutorial has some more examples.
I know this question is old but I came up with a solution that has some advantages:
creates image of correct size.
correct offset.
does not unnecessarily rotate by 0° or 360°.
works for negative angles (e.g. -90°).
works when input is BufferedImage.TYPE_CUSTOM.
As it is, it is assumed that the angle is a multiple of 90°. The only improvement that one might need is to use an Enum for angle instead of just int.
Here's my code:
public static BufferedImage rotateBufferedImage(BufferedImage img, int angle) {
if (angle < 0) {
angle = 360 + (angle % 360);
}
angle %= 360;
if (angle == 0) {
return img;
}
final boolean r180 = angle == 180;
if (angle != 90 && !r180 && angle != 270)
throw new IllegalArgumentException("Invalid angle.");
final int w = r180 ? img.getWidth() : img.getHeight();
final int h = r180 ? img.getHeight() : img.getWidth();
final int type = img.getType() == BufferedImage.TYPE_CUSTOM ? BufferedImage.TYPE_INT_ARGB : img.getType();
final BufferedImage rotated = new BufferedImage(w, h, type);
final Graphics2D graphic = rotated.createGraphics();
graphic.rotate(Math.toRadians(angle), w / 2d, h / 2d);
final int offset = r180 ? 0 : (w - h) / 2;
graphic.drawImage(img, null, offset, -offset);
graphic.dispose();
return rotated;
}
public static BufferedImage rotateBufferedImage(String img, int angle) throws IOException {
return rotateBufferedImage(Paths.get(img), angle);
}
public static BufferedImage rotateBufferedImage(Path img, int angle) throws IOException {
return rotateBufferedImage(ImageIO.read(img.toFile()), angle);
}

Categories