Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to edit the pixels in a BufferedImage?

Tags:

java

pixel

render

After scouring the internet for days, I found a Question that seemed to address my goal. (I'm trying to draw/edit an individual pixel in an image, and render it.) In said question, The ask-er requested code for a Black BufferedImage. The top Answer provided that code, and appears to work beautifully, until you try to change it to something other than black. Here's the Code:

package myProjectPackage;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.*;

public class Copypasta {

public static JFrame frame;
BufferedImage img;
public static int WIDTH = 500;
public static int HEIGHT = 500;

public Copypasta() {
}

public static void main(String[] a){

    Copypasta t=new Copypasta();

    frame = new JFrame("WINDOW");
    frame.setVisible(true);

    t.start();
    frame.add(new JLabel(new ImageIcon(t.getImage())));

    frame.pack();
    // Better to DISPOSE than EXIT
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}

public Image getImage() {
    return img;
}

public void start(){

    img = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
    int[] pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
    boolean running=true;
    while(running){
        BufferStrategy bs=frame.getBufferStrategy();
        if(bs==null){
            frame.createBufferStrategy(4);
            return;
        }
        for (int i = 0; i < WIDTH * HEIGHT; i++)
            pixels[i] = 0; //This is what i've been trying to change.

        Graphics g= bs.getDrawGraphics();
        g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
        g.dispose();
        bs.show();

    }
}
}

I Apologize for the indentation errors. I promise it looks right in the editor.

When set to BufferedImage type ARGB, the black background disappears, causing me to believe that the start function isn't drawing to the Image at all, or the drawn image is not being drawn on the screen. Either way, There is something that I don't understand. If you have the time, I would appreciate some help Identifying What is going wrong, if not an explanation of why. Thank you all, -Navi.

Link to Original Question: drawing your own buffered image on frame

like image 669
Navigatron Avatar asked Apr 23 '14 03:04

Navigatron


1 Answers

Several things jump out, the use of BufferStrategy is probably overkill. Unless you absolutely must have control over the paint process, you really don't need it. Using a BufferStrategy also precludes the use of Swing based components which might or might not be an issue.

Trying to manipulate the pixel data directly is probably also a little overkill, instead you can use BufferedImage.setRGB(int, int, int), which allows you to set the color of the pixel at the specified x/y position, for example...

img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < img.getWidth(); x++) {
    for (int y = 0; y < img.getHeight(); y++) {
        img.setRGB(x, y, Color.RED.getRGB());
    }
}

But, even this is a little overkill, the same thing can be achieved by using the provided 2D Graphics API...

Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.RED);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
g2d.dispose();

Which you will probably find is faster (not just from a coding point of view).

Take a look at:

  • Performing Custom Painting
  • Painting in AWT and Swing
  • 2D Graphics

For more details...

Working example...

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestImage1 {

    public static void main(String[] args) {
        new TestImage1();
    }

    public TestImage1() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage img;

        public TestPane() {
            img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
            //for (int x = 0; x < img.getWidth(); x++) {
            //    for (int y = 0; y < img.getHeight(); y++) {
            //        img.setRGB(x, y, Color.RED.getRGB());
            //    }
            //}

            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.RED);
            g2d.fillRect(0, 0, img.getWidth(), img.getHeight());
            g2d.dispose();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.drawImage(img, 0, 0, this);
            g2d.dispose();
        }
    }

}
like image 89
MadProgrammer Avatar answered Nov 03 '22 00:11

MadProgrammer