I have a sprite sheet that will be 5x5 and each sprite is 20x20 pixels. I need to get each item of that sprite sheet into an array. I made a for loop but got an error. So I tried defining one of the sub images in the array myself but still get an error. I do not get an error when I don't print an item of that array. I now can not figure out the for loop problem.
Here's my code so far
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class LoopSub extends Component {
BufferedImage img;
BufferedImage img2;
BufferedImage bigImg;
BufferedImage[] sprites;
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
g.drawImage(img2, 18, 0, null); //letter size 20x20 ; set lower to overlap
g.drawImage(sprites[0], 36, 0, null); //this is whats causing the error
}
public LoopSub() {
try {
img = ImageIO.read(new File("res/a.png"));
img2 = ImageIO.read(new File("res/b.png"));
/////////////////////////////
bigImg = ImageIO.read(new File("sheet.png"));
final int width = 20;
final int height = 20;
final int rows = 5;
final int cols = 5;
sprites = new BufferedImage[rows * cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
sprites[(i * cols) + j] = bigImg.getSubimage(
j * width,
i * height,
width,
height
);
}
}
sprites[0] = bigImg.getSubimage(1,1,1,1); //where I tried to define the array myself
/////////////////////////////////////////////
} catch (IOException e) {
}
}
public Dimension getPreferredSize() { //sets size of screen
if (img == null) {
return new Dimension(100,100);
} else {
return new Dimension(img.getWidth(null), img.getHeight(null)); //sets size to one image //// change to all images
}
}
public static void main(String[] args) {
JFrame f = new JFrame("Load Image Sample");
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.add(new LoopSub());
f.pack();
f.setVisible(true);
}
}
New error message
Exception in thread "main" java.awt.image.RasterFormatException: (x + width) is outside of Raster
at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)
at java.awt.image.BufferedImage.getSubimage(Unknown Source)
at LoopSub.<init>(LoopSub.java:48)
at LoopSub.main(LoopSub.java:85)
When changing j*width to 1 it works fine. So that's the problem. Just don't know why.
You have a NullPointerException, which means that either sprites or sprites[0] is null.
Given that you initialize them in the constructor, it can happens only if there is an IOException occuring in the constructor, because you are catching it, so it doesn't terminate the program.
You should:
Never silently ignore an exception, like you are doing here. if you don't do anything useful, at least put a message to print the error like this:
} catch (IOException e) {
e.printStackTrace();
}
Look what is the content of the exception, which contains the root of the problem. Probably the program can not find one of your files for some reason.
Edit: for the RasterFormatException, it means that you are getting out of the limits of the image. More specifically, j * width + width is apparently larger than the width of the image.
Since j is at most 4 and width is 20, then the maximum value that j * width + width can have is 100. Your original image should then be at least 100px wide (and also 100px tall). Check that it is indeed the case.
You can for example print the width this way before the loop:
System.out.println("bigImg width: " + bigImg.getWidth());
Related
I am new to programming and I'm currently working on a program that rotates an image to the right and upside down. I was able to get the upside down method working but not the rotate to the right (90 degrees clockwise). It keeps giving me an out of bounds error, and I'm not sure why as I have looked at other examples. Any help would be appreciated.
Here's is the method that I'm working on:
public Image rotateRight()
{
Image right = new Image (this);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int width = right.img.getWidth();
int height = right.img.getHeight();
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++)
{
this.img.setRGB(height-j-1,i,right.img.getRGB(i,j));
}
return right;
}
Here's the rest of the code:
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
public class Image {
private BufferedImage img = null;
int width;
int height;
private Image()
{
}
public Image (int w, int h)
{
img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB );
width = w;
height = h;
}
public Image (Image anotherImg)
{
width = anotherImg.img.getWidth();
height = anotherImg.img.getHeight();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
this.img.setRGB(j,i,anotherImg.img.getRGB(j,i)) ;
}
}
public String toString()
{
return "Width of Image:" +width+"\nHeight of Image:"+height;
}
public Image (String filename)
{
try
{
img = ImageIO.read(new File(filename));
width = img.getWidth();
height = img.getHeight();
}
catch (IOException e)
{
System.out.println(e);
}
}
public void save(String filename, String extension)
{
try
{
File outputfile = new File(filename);
ImageIO.write(img, extension, outputfile);
}
catch (IOException e)
{
System.out.println(e);
}
}
public Image copy()
{
Image copiedImage = new Image(this);
return copiedImage;
}
Here's Main:
public static void main (String args[])
{
Image srcimg = new Image("apple.jpg");
System.out.println(srcimg);
Image copy = srcimg.copy();
copy.save("apple-copy.jpg", "jpg");
Image copy2 = srcimg.copy();
Image right = copy2.rotateRight();
right.save("apple-rotateRight.jpg", "jpg");
}
The reason you are getting an ArrayIndexOutOfBoundsException when rotating your image is as stated. Something is out of bounds. It could be either your i variable that has exceeded its bounds or your j variable that has exceeded its bounds and this is generally easy to test for by just adding a print statement within your for loop and checking which one of the two values is out of bounds. It is good practice to try to resolve these problems yourself as you will start learning what causes these and where the problem lies.
Anyways enough of my rambling. The problem that you seem to have is that you are trying to turn the image without changing the size of the image.
You are creating a new Image with the same width and height parameters as the original
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB );
However when you want to rotate an image by 90 degrees you actually want to flip the width and height parameters. If you think about it, it makes sense when you rotate an image by 90 degrees the width will become the height and the height will become the width.
So your problem is here:
this.img.setRGB(height-j-1,i,right.img.getRGB(i,j));
In your case the bounds for the x parameter in the setRGB function is from 0 to the WIDTH of your image and the y parameter is from 0 to the HEIGHT of your image. Therefore because your height variable is different from your width. If for example your WIDTH is 200 and your HEIGHT is 100. When you put this in to the function the greatest value for the x parameter will be:
'100 - 199 - 1 = -100' which is clearly out of bounds. However if we change your code to.
img = new BufferedImage(height, width, BufferedImage.TYPE_INT_RGB );
now when we do the same thing as before where we get the maximum possible value.
WIDTH = 100, HEIGHT = 200;
'200 - 99 - 1 = 100' which is inside the bounds
Hi guys I know this is a common one, but i've searched around quite a bit and can't seem to get my paint method to draw over the components in my JPanel.
My paint method is linked to a button press. It prints out about 1500 data points and their assigned cluster (kmeans)
package eye_pathscanner;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class ReplayData extends JPanel {
// replay type can be parsed as argument into draw() to change paints behaviour
private int ReplayType = 0;
public ArrayList<DataPoint> points;
//Initialise records
public ReplayData()
{
points = new ArrayList<DataPoint>();
}
public void ReplaceData() {
points = new ArrayList<DataPoint>();
}
public void PrintPoints()
{
}
public void addPoint(DataPoint point) {
points.add(point);
}
#Override
public void paintComponent(Graphics g) {
Color black = new Color(0, 0, 0);
Random random = new Random();
final float luminance = 0.9f;
if (ReplayType == 1)
{
super.paintComponent(g);
for (int x = 0; x < kMeans.NUM_CLUSTERS; x++)
{
// Saturation ideal between 0.1 and 0.3
float saturation = (random.nextInt(2000) + 1000) / 10000f;
float hue = random.nextFloat();
Color cluster_colour = Color.getHSBColor(hue, saturation, luminance);
// Randomise the border colour
saturation = (random.nextInt(2000) + 1000) / 10000f;
hue = random.nextFloat();
Color cluster_colour_border = Color.getHSBColor(hue, saturation, luminance);
double centroidx = kMeans.centroids.get(x).getmX();
double centroidy = kMeans.centroids.get(x).getmY();
for (int i = 0; i < kMeans.TOTAL_DATA; i++)
if(kMeans.dataSet.get(i).cluster() == x){
// Set each child data point to a colour so you can see which cluster it belongs too
g.setColor(cluster_colour);
g.fillRect((int)TrackerData.getRecordNumber(i).getEyeX(),(int)TrackerData.getRecordNumber(i).getEyeY(), 3, 3);
g.drawLine((int)kMeans.dataSet.get(i).X(),(int)kMeans.dataSet.get(i).Y(), (int)centroidx, (int)centroidy);
//g.setColor(Color.black);
g.setColor(cluster_colour_border);
g.drawRect((int)TrackerData.getRecordNumber(i).getEyeX(),(int)TrackerData.getRecordNumber(i).getEyeY(), 3, 3);
}
g.setColor(black);
g.fillOval((int)centroidx,(int)centroidy, 15, 15);
}
}
}
// 1 for K-means with different colour cluster groups
// 2 for slow replay
public void draw(int i) {
ReplayType = i;
repaint();
}
}
This code all works great for me, however I lose the image that was drawn beneath the paint after using it. I can maximize the page and the image shows up again but over the paint? (can anyone explain this behavior).
JLabel picture_panel = new JLabel();
picture_panel.setBounds(70, 130, 640, 797);
picture_panel.addMouseListener(this);
BufferedImage img = null;
try
{
img = ImageIO.read(new File("C:/Eyetracker_Images/Random.jpg")); // eventually C:\\ImageTest\\pic2.jpg
ImageIcon icon = new ImageIcon(img);
picture_panel.setIcon(icon);
}
catch (IOException e)
{
e.printStackTrace();
}
Heres where my image is created, and it's called as shown below on one my buttons
replayData.setBounds(0, 0, 802, 977);
frame.getContentPane().add(replayData);
replayData.draw(1);
Any help would be much appreciated, Thanks.
This maybe an artifact of using setBounds(). Moreover, you appear to be using the default layout manager without invoking pack() on the enclosing container.
As you already have a BufferedImage containing the rendered image, simply invoke drawImage() in your implementation of paintComponent(). Examples are seen here, here and here.
Also consider overriding the getPreferredSize() method of ReplayData, as suggested here and here, to establish its dimensions.
The aim of this little project is to break down an image (in this case a flag) into pieces like a jigsaw and store each piece in part of a 2D array. I then want to be able to view each piece individually so that I know it has worked.
I have created an object class which loads and stores the image. I created the object in my main class and then pass it to my splitImage method which divides the image into chunks and stores in the array. I would like to be able to view a section of the array to check that the splitImage method has worked correctly. Long term however I do need to view the array as I will be determining the colour of the pixel in each image piece and counting how many of each colour is in the image. When I run the current code I get the following in the console,
Exception in thread "main" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
at sample.ImageFrame.splitImage(ImageFrame.java:28)
at sample.ImageFrame.main(ImageFrame.java:59)
28 is the line - BufferedImage image = (BufferedImage)((Image) icon.getImage());
59 is - ImageFrame.splitImage(imageSwing.label);
I have played around with these for some time, changing the position trying other options and have been unsuccessful. Help on this is much appreciated.
Code is below and thanks in advance.
public class ImageSwing extends JFrame
{
public JLabel label;
public ImageSwing()
{
super("Test Image Array");
setLayout(new FlowLayout());
Icon flag = new ImageIcon(getClass().getResource("Italy_flag.jpg"));
label = new JLabel(flag);
label.setToolTipText("Italian Flag");
add(label);
}//main
}//class
public class ImageFrame
{
//public ImageSwing imageSwing = new ImageSwing();
//ImageSwing imageSwing = new ImageSwing();
public static BufferedImage splitImage(JLabel i) throws IOException
{
//Holds the dimensions of image
int rows = 4;
int cols = 4;
ImageIcon icon = (ImageIcon)i.getIcon();
BufferedImage image = (BufferedImage)((Image) icon.getImage());
int chunks = rows * cols; //Total amount of image pieces
int partWidth = i.getWidth() / cols; // determines the piece width
int partHeight = i.getHeight() / rows; //determines the piece height
int count = 0;
BufferedImage[][] flagArray = new BufferedImage[rows][cols]; //2D Array to hold each image piece
for (int x = 0; x < rows; x++)
{
for (int y = 0; y < cols; y++)
{
//Initialize the image array with image chunks
flagArray[x][y] = new BufferedImage(partWidth, partHeight, image.getType());
// draws the image chunk
Graphics2D gr = flagArray[x][y].createGraphics();
gr.drawImage(image, 0, 0, partWidth, partHeight, partWidth * y, partHeight * x, partWidth * y + partWidth, partHeight * x + partHeight, null);
gr.dispose();
}
}
return flagArray[rows][cols];
}
public static void main(String[] args)
{
ImageSwing imageSwing = new ImageSwing();
try
{
ImageFrame.splitImage(imageSwing.label);
} catch (IOException e)
{
e.printStackTrace();
}
imageSwing.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
imageSwing.setSize(260,180);
imageSwing.setVisible(true);
}//main
}//class
Take a look at Java converting Image to BufferedImage
It provides a way to convert from Image to BufferedImage, which seems to be the problem.
I want to draw a grid and draw stuff in the cells (to keep things easy just fill them).
Overall I've got it pretty much working only in some panel sizes the cell is about 1 pixel off of where it should be placed (overlapping the line).
TBH I haven't really done enough calculating to possibly find the answer myself, so my apologies for that, I'm really not too sure how to approach this "bug" either though.
Anyway, here's the code:
public class Gui extends JFrame {
public static void main(String[] args) {
new Gui().setVisible(true);
}
public Gui() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
add(new JPanel() {
public static final int SIZE = 3;
/** Line thickness ratio to a block */
public static final float LINE_THICKNESS = 0.1f;
/** #return the width of a block. */
protected final int getBlockWidth() {
return getWidth() / SIZE;
}
/** #return the height of a block. */
protected final int getBlockHeight() {
return getHeight() / SIZE;
}
/** #return the width of a cell. */
protected final int getCellWidth() {
return (int) Math.ceil(getBlockWidth()*(1-LINE_THICKNESS));
}
/** #return the height of a cell. */
protected final int getCellHeight() {
return (int) Math.ceil(getBlockHeight()*(1-LINE_THICKNESS));
}
#Override
public void paintComponent(Graphics g) {
g.setColor(new Color(0, 0, 255, 100));
int lineWidth = (int) (LINE_THICKNESS * getBlockWidth());
int lineHeight = (int) (LINE_THICKNESS * getBlockHeight());
for(int i = 0; i <= SIZE; i++) {
g.fillRect(i * getBlockWidth() - lineWidth / 2, 0, lineWidth, getHeight());
g.fillRect(0, i * getBlockHeight() - lineHeight/2, getWidth(), lineHeight);
}
g.setColor(new Color(255, 0, 0, 100));
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
int x = j * getBlockWidth() + lineWidth/2;
int y = i * getBlockHeight() + lineHeight/2;
Graphics temp = g.create(x, y, getCellWidth(), getCellHeight());
drawCell(temp, i, j);
}
}
}
private void drawCell(Graphics g, int i, int j) {
g.fillRect(0, 0, getCellWidth(), getCellHeight());
}
});
setLocation(new Point(500, 200));
setSize(new Dimension(600, 600));
}
}
If you run it you'll probably see what I mean. I can't think of a good explanation in words. At first I thought I had to add + 1 to x and y since I want to draw next to the line, but this (obviously) just shifts the problem to the other side.
Running this with a SIZE bigger (like 30) gives me another bug that it gives open space to the sides. I know (or assume) this is because I'm using integers and it isn't too big of a deal though. But hints for a better approach (in general) are always welcome.
There are several ways you can fix this. I will not give you code, since I believe (based on how you asked your question) you are one of those who like to think and solve problems on their own.
First of all: first draw the background on the whole panel and then draw the lines. There'll be no while lines and the drawing will be slightly faster.
Second way: the order of drawing is important. You can safely draw the background first (even if it overlaps) and then overwrite it with borders.
Third way: do not use ints. Use floats or doubles. All your trouble will go away.
Fourth way: calculate the remainder. You can predict when the lines are drawn and when not, think about it. Predict it and draw appropriately.
Hi I had your same problem but the solution I implemented is inspired by the sample available from the Java Tutorial for drawing multiline text and draws the text on the cell using the text APIs.
http://java.sun.com/docs/books/tutorial/2d/text/drawmulstring.html
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.text.BreakIterator;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class MultilineTableCell
implements TableCellRenderer {
class CellArea extends DefaultTableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
private String text;
protected int rowIndex;
protected int columnIndex;
protected JTable table;
protected Font font;
private int paragraphStart,paragraphEnd;
private LineBreakMeasurer lineMeasurer;
public CellArea(String s, JTable tab, int row, int column,boolean isSelected) {
text = s;
rowIndex = row;
columnIndex = column;
table = tab;
font = table.getFont();
if (isSelected) {
setForeground(table.getSelectionForeground());
setBackground(table.getSelectionBackground());
}
}
public void paintComponent(Graphics gr) {
super.paintComponent(gr);
if ( text != null && !text.isEmpty() ) {
Graphics2D g = (Graphics2D) gr;
if (lineMeasurer == null) {
AttributedCharacterIterator paragraph = new AttributedString(text).getIterator();
paragraphStart = paragraph.getBeginIndex();
paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g.getFontRenderContext();
lineMeasurer = new LineBreakMeasurer(paragraph,BreakIterator.getWordInstance(), frc);
}
float breakWidth = (float)table.getColumnModel().getColumn(columnIndex).getWidth();
float drawPosY = 0;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position. If the paragraph is right-to-left we
// will align the TextLayouts to the right edge of the panel.
// Note: this won't occur for the English text in this sample.
// Note: drawPosX is always where the LEFT of the text is placed.
float drawPosX = layout.isLeftToRight()
? 0 : breakWidth - layout.getAdvance();
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
table.setRowHeight(rowIndex,(int) drawPosY);
}
}
}
public Component getTableCellRendererComponent(
JTable table, Object value,boolean isSelected, boolean hasFocus, int row,int column
)
{
CellArea area = new CellArea(value.toString(),table,row,column,isSelected);
return area;
}
}
It resizes row heigth too but it does it well only when this renderer is used for a single column.
And this is the way I used to invoke it for render my table.
final int wordWrapColumnIndex = ...;
myTable = new JTable() {
public TableCellRenderer getCellRenderer(int row, int column) {
if (column == wordWrapColumnIndex ) {
return wordWrapRenderer;
}
else {
return super.getCellRenderer(row, column);
}
}
};
I am writing a Buddhabrot fractal generator using aparapi. I got the OpenCL part of it to work, resulting in a single-dimension array that represents each pixel. I have the dimensions of the final image as final ints, and have written code to get the index of arbitrary points in that array. I want to save this as an image and I'm trying to use BufferedImage with TYPE_USHORT_GRAY. Here's what I have so far:
BufferedImage image=new BufferedImage(VERTICAL_PIXELS, HORIZONTAL_PIXELS, BufferedImage.TYPE_USHORT_GRAY);
for(int i=0; i<VERTICAL_PIXELS; i++)
for(int k=0; k<HORIZONTAL_PIXELS; k++)
image.setRGB(k, i, normalized[getArrayIndex(k,i,HORIZONTAL_PIXELS)]);
The problem is, I don't know what to set the RGB as. What do I need to do?
The problem here is that setRGB() wants an 0xRRGGBB color value. BufferedImage likes to pretend that the image is RGB, no matter what the data is stored as. You can actually get at the internal DataBufferShort (with getTile(0, 0).getDataBuffer()), but it can be tricky to figure out how it is laid out.
If you already have your pixels in a short[], a simpler solution might be to copy them into an int[] instead an jam it into a MemoryImageSource:
int[] buffer = /* pixels */;
ColorModel model = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY), new int[] { 16 },
false, true, Transparency.OPAQUE, DataBuffer.TYPE_USHORT);
Image image = Toolkit.getDefaultToolkit().createImage(
new MemoryImageSource(VERTICAL_PIXELS, HORIZONTAL_PIXELS,
model, buffer, 0, VERTICAL_PIXELS));
The advantage of this approach is that you control the underlying pixel array. You could make changes to that array and call newPixels() on your MemoryImageSource, and it would update live. It also gives you complete power to define your own palette other than grayscale:
int[] cmap = new int[65536];
for(int i = 0; i < 65536; ++i) {
cmap[i] = (((i % 10000) * 256 / 10000) << 16)
| (((i % 20000) * 256 / 20000) << 8)
| (((i % 40000) * 256 / 40000) << 0);
}
ColorModel model = new IndexColorModel(16, 65536, cmap, 0, false, -1, DataBuffer.TYPE_USHORT);
This approach works fine if you just want to display the image on the screen:
JFrame frame = new JFrame();
frame.getContentPane().add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
However, if you wanted to write it out to a file and preserve the one-short-per-pixel format (say, to load into Matlab) then you're out of luck. The best you can do is to paint it into a BufferedImage and save that with ImageIO, which will save as RGB.
If you definitely need a BufferedImage at the end, another approach is to apply the color palette yourself, calculate the RGB values, and then copy them into the image:
short[] data = /* your data */;
int[] cmap = /* as above */;
int[] rgb = new int[data.length];
for(int i = i; i < rgb.length; ++i) {
rgb[i] = cmap[data[i]];
}
BufferedImage image = new BufferedImage(
VERTICAL_PIXELS, HORIZONTAL_PIXELS,
BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, VERTICAL_PIXELS, HORIZONTAL_PIXELS,
pixels, 0, VERTICAL_PIXELS);
For reference, this example shows how two different BufferedImage types interpret the same 16 bit data. You can mouse over the images to see the pixel values.
Addendum: To elaborate on the word interpret, note that setRGB() tries to find the closest match to the specified value in the given ColorModel.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
/** #see http://stackoverflow.com/questions/8765004 */
public class BufferedImageTest extends JPanel {
private static final int SIZE = 256;
private static final Random r = new Random();
private final BufferedImage image;
public BufferedImageTest(int type) {
image = new BufferedImage(SIZE, SIZE, type);
this.setPreferredSize(new Dimension(SIZE, SIZE));
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
image.setRGB(col, row, 0xff00 << 16 | row << 8 | col);
}
}
this.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
int x = p.x * SIZE / getWidth();
int y = p.y * SIZE / getHeight();
int c = image.getRGB(x, y);
setToolTipText(x + "," + y + ": "
+ String.format("%08X", c));
}
});
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}
static private void display() {
JFrame f = new JFrame("BufferedImageTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new GridLayout(1, 0));
f.add(new BufferedImageTest(BufferedImage.TYPE_INT_ARGB));
f.add(new BufferedImageTest(BufferedImage.TYPE_USHORT_GRAY));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
display();
}
});
}
}