I have a squared PGraphics where I want to read the color of each pixel. I do this with the following lines:
size(1080,1080, P2D);
pg = createGraphics(width, height, P2D);
…then in draw:
pg.loadPixels();
for (int y = 0; y < pixel; y++) {
for (int x = 0; x < pixel; x++) {
int ix = int(size*x);
int iy = int(size*y);
color c = pg.pixels[iy * width + ix];
However, if I now change the size so that the PGrpahics or my sketch window is no longer squared I get an ArrayIndexOutOfBoundsException error message. I know that you can also read the pixels from rectangular sketches, for example with:
pixels[x+y*width] = …etc
Works fine – but what is it that I am missing above if I change the size to lets say size(1920,1080, P2D);?
Related
Let's say I have an image called testimage.jpg, and want to cross-stitch it with a DMC 208 floss (RGB value: 148,91,128)
I got these hints:
Read each pixel's RGB value
Compare it with the floss
Use bilinear interpolation for image scaling
Use Euclidean distance to get the closest color
I think I already figured out how to do step 1. Now I'm wondering how to do step 2, and 4.
BufferedImage img = ImageIO.read(new File("testimage.jpg"));
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();
Color dmc208 = new Color(148,91,128);
Color currentPixel = null;
for (int x = 0; x < imgWidth; x++){
for (int y = 0; y < imgHeight; y++){
currentPixel = new Color(img.getRGB(x, y));
}
}
I know how to calculate the Eulicdean distance, but how to get the"closest" color at that distance?
I have been business a histogram equalisation method. I've used this question as a foundation to build on. However I cannot get this code to run and Google isn't too helpful in helping me find the issue. I pass in a JPG BufferedImage object. I first display the image so I see what I'm working with and then process it. However it ALWAYS fails on the line int valueBefore=img.getRaster().getPixel(x, y,iarray)[0]; and I'm not sure why. The error I get is Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 but I cannot see why it gives this error, the picture is there and filled with pixels!
public BufferedImage hisrogramNormatlisation(BufferedImage img) {
// To view image we're working on
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(img)));
frame.pack();
frame.setVisible(true);
int width =img.getWidth();
int height =img.getHeight();
int anzpixel= width*height;
int[] histogram = new int[255];
int[] iarray = new int[1];
int i =0;
// Create histogram
for (int x = 50; x < width; x++) {
for (int y = 50; y < height; y++) {
int valueBefore=img.getRaster().getPixel(x, y,iarray)[0];
histogram[valueBefore]++;
System.out.println("here");
}
}
int sum = 0;
float[] lut = new float[anzpixel];
for ( i=0; i < 255; ++i )
{
sum += histogram[i];
lut[i] = sum * 255 / anzpixel;
}
i=0;
for (int x = 1; x < width; x++) {
for (int y = 1; y < height; y++) {
int valueBefore=img.getRaster().getPixel(x, y,iarray)[0];
int valueAfter= (int) lut[valueBefore];
iarray[0]=valueAfter;
img.getRaster().setPixel(x, y, iarray);
i=i+1;
}
}
return img;
}
Error description:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at java.awt.image.ComponentSampleModel.getPixel(ComponentSampleModel.java:n)
at java.awt.image.Raster.getPixel(Raster.java:n)
at MainApp.hisrogramNormatlisation(MainApp.java: * line described *)
at MainApp.picture(MainApp.java:n)
at MainApp.<init>(Main.java:n)
at MainApp.main(Main.java:n)
The stack trace you posted says your out of range index is 1.
The exception isn't thrown where you think it is.
getPixel(int x, int y, int[] iarray) fills iarray with the intensity values of the pixel. If you are using an rgb image, there will be at least three intensity values for each channel, if you are using rgb with alpha there will be 4 intensity values. Your iarray is just of size 1, so when raster wants to access further elements to store the additional values an IndexOutOfBoundsException is thrown.
Increase the size of iarray and the exception will be gone.
Don't use getPixel(), but getSample().
So your code would be: final int valueBefore = img.getRaster().getSample(x, y, 0) ; or even histogram[img.getRaster().getSample(x, y, 0)]++ ;
Btw, you may want to check the image type first in order to determine the number of channels/bands and do this process for each channel.
I'm trying to understand why a
bufferedImg.setRGB(x, y, color.getRGB());
sets no data (white pixels) at all, if I print one immediately before it by
System.out.println(color.getRGB());
as in following java code:
...
int height = img.getHeight();
int width = img.getWidth();
for(int i = 0; i < height; i++){
for(int j = 0; j < width; j++){
Color c = new Color(img.getRGB(j, i));
int red = (int)(c.getRed() * 0.299);
int green = (int)(c.getGreen() * 0.587);
int blue = (int)(c.getBlue() *0.114);
Color newColor = new Color(red + green + blue,
red + green + blue, red + green + blue);
System.out.println(newColor.getRGB()); // resets data
img.setRGB(j, i, newColor.getRGB());
}
}
Additional infos:
Its an implementation for converting RGB to grayscale
it works perfectly fine by removing the print/log line
(multiple) calls of println() before or/and after shows correct data
buffered image source is an openCV mat
i didnt find any specific reasons on the internet
Hoping for a person to give me some insight.
I have an image that is stored as an array of pixel values. I want to be able to apply a brightness or contrast filter to this image. Is there any simple way, or algorithm, that I can use to achieve this.
Here is my code...
PlanarImage img=JAI.create("fileload","C:\\aimages\\blue_water.jpg");
BufferedImage image = img.getAsBufferedImage();
int w = image.getWidth();
int h = image.getHeight();
int k = 0;
int[] sbins = new int[256];
int[] pixel = new int[3];
Double d = 0.0;
Double d1;
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
pixel = bi.getRaster().getPixel(x, y, new int[3]);
k = (int) ((0.2125 * pixel[0]) + (0.7154 * pixel[1]) + (0.072 * pixel[2]));
sbins[k]++;
}
}
My suggestion would be to use the built-in methods of Java to adjust the brightness and contrast, rather than trying to adjust the pixel values yourself. It seems pretty easy by doing something like this...
float brightenFactor = 1.2f
PlanarImage img=JAI.create("fileload","C:\\aimages\\blue_water.jpg");
BufferedImage image = img.getAsBufferedImage();
RescaleOp op = new RescaleOp(brightenFactor, 0, null);
image = op.filter(image, image);
The float number is a percentage of the brightness. In my example it would increase the brightness to 120% of the existing value (ie. 20% brighter than the original image)
See this link for a similar question...
Adjust brightness and contrast of BufferedImage in Java
See this link for an example application...
http://www.java2s.com/Code/Java/Advanced-Graphics/BrightnessIncreaseDemo.htm
I'm attempting to take a picture as input, then manipulate said picture (I specifically want to make it greyscale) and then output the new image. This is a snippet of the code that I'm editing in order to do so but I'm getting stuck. Any ideas of what I can change/do next. Greatly appreciated!
public boolean recieveFrame (Image frame) {
int width = frame.width();
int height = frame.height();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
Color c1 = frame.get(i, j);
double greyScale = (double) ((Color.red *.3) + (Color.green *.59) + (Color.blue * .11));
Color newGrey = Color.greyScale(greyScale);
frame.set(i, j, newGrey);
}
}
boolean shouldStop = displayImage(frame);
return shouldStop;
}
I'm going to try to stick as close as possible to what you already have. So, I'll assume that you are looking for how to do pixel-level processing on an Image, rather than just looking for a technique that happens to work for converting to greyscale.
The first step is that you need the image to be a BufferedImage. This is what you get by default from ImageIO, but if you have some other type of image, you can create a BufferedImage and paint the other image into it first:
BufferedImage buffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = buffer.createGraphics();
g.drawImage(image, 0, 0);
g.dispose()
Then, you can operate on the pixels like this:
public void makeGrey(BufferedImage image) {
for(int x = 0; x < image.getWidth(); ++x) {
for(int y = 0; y < image.getHeight(); ++y) {
Color c1 = new Color(image.getRGB(x, y));
int grey = (int)(c1.getRed() * 0.3
+ c1.getGreen() * 0.59
+ c1.getBlue() * .11
+ .5);
Color newGrey = new Color(grey, grey, grey);
image.setRGB(x, y, newGrey.getRGB());
}
}
}
Note that this code is horribly slow. A much faster option is to extract all the pixels from the BufferedImage into an int[], operate on that, and then set it back into the image. This uses the other versions of the setRGB()/getRGB() methods that you'll find in the javadoc.