Reputation: 83
Could get a similar effect to this
https://www.youtube.com/watch?v=ubFq-wV3Eic
in Java? The goal is to have it as fast as possible - my mission is to find out if it's possible to burn pixels in my lcd this way. It may sound ridiculous, but I still need to find out.
Upvotes: 0
Views: 183
Reputation: 44328
The links Spektre shared say that 16 levels of gray are enough, so you can generate a random value in the [0, 15] range, and multiply that to get a pixel value.
Since you’re concerned about speed, you can directly manipulate the DataBuffer of a BufferedImage to update the pixels. TYPE_USHORT_GRAY guarantees an image with a ComponentColorModel and ComponentSampleModel:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferUShort;
import java.awt.image.ComponentSampleModel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.util.Random;
public class NoiseGenerator
extends JPanel {
private static final long serialVersionUID = 1;
private static final int FPS = Math.max(1, Integer.getInteger("fps", 30));
private final int width;
private final int height;
private final BufferedImage image;
private final Random random = new Random();
public NoiseGenerator(GraphicsDevice screen) {
this(screen.getDefaultConfiguration().getBounds().getSize());
}
public NoiseGenerator(Dimension size) {
this(size.width, size.height);
}
public NoiseGenerator(int width,
int height) {
this.width = width;
this.height = height;
this.image = new BufferedImage(width, height,
BufferedImage.TYPE_USHORT_GRAY);
setFocusable(true);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
private void generateFrame() {
DataBufferUShort buffer = (DataBufferUShort)
image.getRaster().getDataBuffer();
short[] data = buffer.getData();
ComponentSampleModel sampleModel = (ComponentSampleModel)
image.getSampleModel();
int stride = sampleModel.getScanlineStride();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
data[y * stride + x] = (short) (random.nextInt(16) * 4096);
}
}
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
public void start() {
Timer timer = new Timer(1000 / FPS, e -> generateFrame());
timer.start();
}
public static void main(String[] args) {
int screenNumber = args.length > 0 ? Integer.parseInt(args[0]) : -1;
EventQueue.invokeLater(() -> {
GraphicsEnvironment env =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice screen = env.getDefaultScreenDevice();
if (screenNumber >= 0) {
GraphicsDevice[] screens = env.getScreenDevices();
if (screenNumber >= screens.length) {
System.err.println("Cannot detect screen " + screenNumber);
System.exit(2);
}
screen = screens[screenNumber];
}
NoiseGenerator generator = new NoiseGenerator(screen);
generator.start();
JFrame window = new JFrame("Noise Generator",
screen.getDefaultConfiguration());
window.setUndecorated(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
generator.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
System.exit(0);
}
});
generator.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent event) {
System.exit(0);
}
@Override
public void keyPressed(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
});
window.getContentPane().add(generator);
screen.setFullScreenWindow(window);
});
}
}
Upvotes: 3