I am wanting to get rgb value of each pixel in an image. For this I used getRGB() which returns an integer that I converted with Color(arg,true). If I print out the getRGB() results and paste one of the numbers into the Color class it works. But if make an integer as shown equal rgb and put it in Color so I can cycle through each pixel it returns 255 for all values.
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.File;
import java.io.IOException;
import javax.imageio.*;
public class kmeans {
public static void main(String[] args) throws IOException {
File file = new File("andy.jpg");
BufferedImage image = ImageIO.read(file);
int width = image.getWidth();
int height = image.getHeight();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int rgb = image.getRGB(i, j);
// System.out.println(rgb);
Color c = new Color(rgb, true);
// System.out.println(c.getRed()+" "+c.getGreen()+" "+c.getBlue()+" ");
System.out.println(c);
}
}
}
}
Have you tried setting new Color(rgb, true) to new Color(rgb, false)? When you get the int value for rgb, you don't get the alpha value (aka the transparency of the current pixel). When using that value in the constructor, without having an alpha value, it could mess with the results.
I think your code is fine and the problem, assuming there is one, is elsewhere. Here is a sample of the output your code produced for some random JPEG:
java.awt.Color[r=126,g=116,b=104]
java.awt.Color[r=122,g=112,b=100]
java.awt.Color[r=116,g=106,b=94]
java.awt.Color[r=117,g=107,b=95]
java.awt.Color[r=123,g=113,b=101]
java.awt.Color[r=122,g=112,b=100]
Related
I am working on a project in which I am trying to store all the pixels of a jpg image in an array, and then using that array to write a copy of the original image in a different folder. However, I do not seem to be able to write the copy into the folder. I know that the issue has something to do with the copy of the image I created, since the writing works perfectly if I use the original image as the parameter in ImageIO.write, but i'm still not entirely sure what the issue is. Does anyone know what sort of error I may be encountering, and what I could do to fix it? (For additional context, I know that reading/writing can be implemented without using arrays, but I want to use arrays to implement this)
Code for reference:
package com.company;
import java.io.File;
import java.util.Scanner;
import java.util.concurrent.*;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
public class filereader {
public static void main(String[] args) throws IOException {
int width = 1536;
int height = 2048;
BufferedImage image = null;
BufferedImage newimage = null;
int[][] newarray = new int[height][width];
File f = null;
File g = null;
try {
System.out.println("Insert your file");
Scanner scanney = new Scanner(System.in);
String arg1 = scanney.next();
f = new File(arg1);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
image = ImageIO.read(f);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
newarray[i][j] = image.getRGB(j, i);
}
}
} catch (IOException e) {
System.out.println("Error:" + e);
}
try {
newimage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
System.out.println(newimage.getType());
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int newimagestuff = newarray[i][j];
newimage.setRGB(j, i, newimagestuff);
}
}
int i = 0;
g = new File("C:\\Users\\user1\\Documents\\File Reading\\Outputest.jpg");
ImageIO.write(newimage,"jpg", g);
System.out.println(newimage);
System.out.println(image);
} catch (IOException e) {
System.out.println("Error:" + e);
}
}
}
There are several issues with your code:
You create two new BufferedImages - the first one is completely useless as you are overwriting it in the next line with the result of ImageIO.read().
The second BufferedImage you create has the type BufferedImage.TYPE_INT_ARGB which is probably wrong as JPG images don't have an alpha channel (thats the "A" in the type). You rather should use the type of the image read in with ImageIO.
Also why do you copy pixel by pixel when you could read always a complete row - if it has to be a two-dimensional array for intermediate storage - or even the complete image at once - if a single-dimensional image would suffice. You can use public int[] getRGB​(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) and the matching setRGB method for this.
I think escaping the space in your file path might help. Like that:
g = new File("C:\\Users\\user1\\Documents\\File\ Reading\\Outputest.jpg");
I am trying to convert my 2d list of Colors to an actual image and then export it, however, when I try to use it, it distorts the colors (shows the wrong ones)
import javafx.scene.paint.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
public class ImageAction {
public static void fromColorGrid(List<List<Color>> colorGrid) {
int width = colorGrid.size();
int height = colorGrid.get(0).size();
BufferedImage buffImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// Set each pixel of the BufferedImage to the color from the Color[][].
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
String colorStr = colorGrid.get(x).get(y).toString().replace("0x", "");
int rgb = Integer.parseInt(colorStr, 16);
System.out.println(colorStr + " " + rgb);
buffImage.setRGB(x, y, rgb);
}
}
try {
File outputfile = new File("saved.png");
ImageIO.write(buffImage, "png", outputfile);
} catch (IOException e) {
System.out.println("Ups");
}
}
}
Where am I going wrong?
This bit seems odd to me:
String colorStr = colorGrid.get(x).get(y).toString().replace("0x", "");
int rgb = Integer.parseInt(colorStr, 16);
System.out.println(colorStr + " " + rgb);
buffImage.setRGB(x, y, rgb);
That code relies on toString() method of JavaFX's color class, which explicitly states:
This method is intended to be used only for informational purposes. The content and format of the returned string might vary between implementations.
Instead, just convert directly to an AWT color using the RGB values:
Color fxColor = colorGrid.get(x).get(y);
java.awt.Color awtColor = new java.awt.Color((float) fxColor.getRed(),
(float) fxColor.getGreen(),
(float) fxColor.getBlue(),
(float) fxColor.getOpacity());
buffImage.setRGB(x, y, awtColor.getRGB());
The above doesn't rely on any particular toString() implementation, and in my quick tests the code seems to work fine with it in place.
This code is a test for a larger program I'm building. It is supposed to color every other pixel row in the image red, but the result is the image added below. Can somebody explain why the red isn't showing?
package code;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class Pixel {
BufferedImage image;
int width;
int height;
public Pixel() throws IOException {
File input = new File("/Users/SanchitBatra/Desktop/Depixelator.jpg");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
}
public void changePixels() throws IOException{
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
int red;
// Color c = new Color(image.getRGB(j, i));
if(i%2==0){
red = 255;
}
else{
red=0;
}
int green = 0;
int blue = 0;
Color newColor = new Color(red, green, blue);
image.setRGB(j,i,newColor.getRGB());
}
}
File output = new File("/Users/SanchitBatra/Desktop/grayscale.jpg");
ImageIO.write(image, "jpg", output);
}
static public void main(String args[]) throws Exception {
Pixel obj = new Pixel();
obj.changePixels();
}
}
This is the resulting image:
Edit: The program is doing exactly what it should using a coloured image as a source. Thanks to all contributions! I learnt a lot today :)
Try this:
public void changePixels() throws IOException{
BufferedImage bi = new BufferedImage(side,side,BufferedImage.TYPE_INT_ARGB);
int[] pixels = new int[width*height];
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
int colorIn = image.getRGB(j,i);
int redIn = 255&(colorIn<<16);
int greenIn = 255&(colorIn<<8);
int blueIn = 255&(colorIn);
if(i%2==0){
redIn = 255;
}
pixels[i+j*width] = (255<<24)|(redIn<<16)|(greenIn<<8)|blueIn;
}
}
bi.setRGB(0, 0, width, height, pixels, 0, width);
File output = new File("/Users/SanchitBatra/Desktop/grayscale.jpg");
ImageIO.write(bi, "jpg", output);
}
I showed you how to pull the color values out using bit shifting here to show you how to have a little bit more control over your process. This also retains the original pixel values and just overwrites the red value if it is an even column.
If you want to make columns red, you should make them red along the width instead of the height. The current code will make alternate rows red.
I think your code is OK, try to zoom in/out in your image to see if you are getting the desired effects.
Thanks,
Hassaan
i am trying to generate following given sateen design with help of my java code but this code is not creating png file named sateen
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Sateen {
BufferedImage image;
int width;
int height;
int red,green,blue;
public Sateen() {
try {
File input = new File("n.png");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
//n is png file with only white pixels
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
Color p = new Color(image.getRGB(j, i));
Color g = new Color(image.getRGB(j+5, i));
//getting (j,i) coordinate pixel value and then comparing it to next 5th pixel
if(p.getRed()==255&&p.getBlue()==255&&p.getGreen()==255&&g.getRed()==255&&
g.getBlue()==255&&g.getGreen()==255)
{ red=0;
blue=0;
green=0; }
//if both pixel value is white then setting 5th pixel value to black
Color newColor = new Color(red,green,blue);
image.setRGB(j+5,i,newColor.getRGB());
j=j+5;
}
}
File ouptut = new File("Sateen.png");
ImageIO.write(image, "png", ouptut);
//creating sateen png file
} catch (Exception e) {}
}
static public void main(String args[]) throws Exception
{
Sateen obj = new Sateen();
}
}
Seems to actually create a .png file (make sure the filepath is correct?). However this code will not generate a sateen pattern, rather draws black pixels at column 6, 12, 18 etc.
The following code fixes some issues in your code. Although it produces an output file but the output file does not look like what you are trying to produce. Perhaps you need to tweak your algorithm?
Anyway the main thing to learn here is that if you are looping over arrays and incrementing the index within the loop then you need to take care of the situation where your index might go out of bounds of the array i.e. your j+5 can be anything outside the image.
Also, make sure that your input file is in the correct location which will depend on where you run the program from. If you run it from the debugger/IDE then it should be inside the project folder next to the src folder. It would be better if you specify full path to your file i.e. C:\SomeFolder\n.png to avoid input file missing error.
Finally, use something like e.printStackTrace(); in your catch block to find out where and why your code is failing.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Sateen {
BufferedImage image;
int width;
int height;
int red, green, blue;
public Sateen() {
try {
File input = new File("n.png");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
// n is png file with only white pixels
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) { // may not need j++ as you are doing j+5?
Color p = new Color(image.getRGB(j, i));
int jPlus5 = j + 5;
if (jPlus5 < width) {
Color g = new Color(image.getRGB(jPlus5, i));
// getting (j,i) coordinate pixel value and then
// comparing
// it to next 5th pixel
if (p.getRed() == 255 && p.getBlue() == 255 && p.getGreen() == 255 && g.getRed() == 255 &&
g.getBlue() == 255 && g.getGreen() == 255)
{
red = 0;
blue = 0;
green = 0;
}
// if both pixel value is white then setting 5th pixel
// value
// to black
Color newColor = new Color(red, green, blue);
image.setRGB(jPlus5, i, newColor.getRGB());
}
j = jPlus5;
}
}
File ouptut = new File("Sateen.png");
ImageIO.write(image, "png", ouptut);
// creating sateen png file
} catch (Exception e) {
e.printStackTrace();
}
}
static public void main(String args[]) throws Exception
{
Sateen obj = new Sateen();
}
}
I am very much a beginner in digital image processing and programming in general. I am trying to find the Mean of an image using a raster. To be completely honest, this is a real stab in the dark but I am really lost at what to do here.
My code currently returns nothing and I am not sure if it is even doing anything. My interpretation of what it is doing is, read the image file and then using a raster to extract the details of that image based on height and width cooridinates. I want it basically to output the mean on the console.
So could anybody tell me what I am doing wrong and why my code is not returning the mean of the image? I have been digging up resources to try and learn but anything linked with image processing doesn't really seem to be for a newbie and I am finding it tough. So if anyone has anywhere that would be good to start it would be appreciated.
Eventually, I want to calculate the mean on one image and I then want to run that image against a file directory of other images. The point of this is to see which images are most similar based on the mean. But I feel like I am some way off where I want to be.
Here is my code
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class calculateMean {
static BufferedImage image;
static int width;
static int height;
public static void main(String[] args) throws Exception{
try{
File input = new File("C:\\Users\\cbirImages\\jonBon2.jpg");
image = ImageIO.read(input);
width = image.getWidth();
height = image.getHeight();
}catch (Exception c){}
}
private double sum;
public double imageToCalculate(){
int count = 0;
for(int i=0; i<height; i++){
for(int j=0; j<width; j++){
count++;
Raster raster = image.getRaster();
double sum = 0.0;
for (int y = 0; y < image.getHeight(); ++y){
for (int x = 0; x < image.getWidth(); ++x){
sum += raster.getSample(x, y, 0);
}
}
return sum / (image.getWidth() * image.getHeight());
}
}
System.out.println("Mean Value of Image is " + sum);
return sum;
}
}
You go through all the pixels twice in your method imageToCalculate. This simple code is enough to compute the average of an image:
for (int y = 0; y < image.getHeight(); ++y)
for (int x = 0; x < image.getWidth(); ++x)
sum += raster.getSample(x, y, 0) ;
return sum / (image.getWidth() * image.getHeight());
But usually, it's better to give the image as a parameter of the method:
public double Average(BufferedImage image)
And for the final purpose of your project, there is no way that the average can give you a good result. Imagine that you have two images: the first with all the pixels at 127, and the second with half of the pixels at 0 and the other at 255.