identify Blank Image Using Java - java

Hi How can we identify Blank Image(White Image),
BufferReaderImage im = ImageIO.read("samplePath");
the image iam passing is empty with some height and width, i want to identify it

This link should help you get started:
Get RGB values of a BufferedImage
In particular, this is the relevant part:
BufferedImage image = ImageIO.read(
new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
int w = image.getWidth();
int h = image.getHeight();
int[] dataBuffInt = image.getRGB(0, 0, w, h, null, 0, w);
Color c = new Color(dataBuffInt[100]);
System.out.println(c.getRed()); // = (dataBuffInt[100] >> 16) & 0xFF
System.out.println(c.getGreen()); // = (dataBuffInt[100] >> 8) & 0xFF
System.out.println(c.getBlue()); // = (dataBuffInt[100] >> 0) & 0xFF
System.out.println(c.getAlpha()); // = (dataBuffInt[100] >> 24) & 0xFF
Then go through all the entries and make sure there are some different values.

Related

How to obtain the red, green and blue values from gray value in java?

I obtain the gray value of the pixel by :
val=img.getRGB(j, i) & 0xFF;
for processing purpose.
Now , after processing I want the red, green and blue values back. How do I do this?
Here is some sample code to obtain the r, g, b, alpha, and gray-scale values for a pixel at coordinates (x, y) on a BufferedImage.
BufferedImage image; // assume you have this image
int rgb = image.getRGB(x, y); // get the desired pixel
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = (rgb & 0xFF);
int alpha = (rgb >> 24) & 0xFF;
int gray = (r + g + b) / 3; // rgb are not affected
Use the below:-
int r=(rgb>>16) & 0xff;
int g=(rgb>>8) & 0xff;
int b=(rgb) & 0xff;
where int rgb=img.getRGB(j, i);
Store these values for later retrieval.
Refer: RGB values of an image
In case of a gray image:-
int rgb = (val << 16) | (val << 8) | (val << 0);
You can get the rgb value of gray image like above, and then apply the methods of finding r,g and b as mentioned earlier.

Getting all RGB colors of an image

So far I have this:
BufferedImage image = ImageIO.read(
new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
int w = image.getWidth();
int h = image.getHeight();
int[] dataBuffInt = image.getRGB(0, 0, w, h, null, 0, w);
Color c = new Color(dataBuffInt[100]);
System.out.println(c.getRed()); // = (dataBuffInt[100] >> 16) & 0xFF
System.out.println(c.getGreen()); // = (dataBuffInt[100] >> 8) & 0xFF
System.out.println(c.getBlue()); // = (dataBuffInt[100] >> 0) & 0xFF
System.out.println(c.getAlpha()); // = (dataBuffInt[100] >> 24) & 0xFF
Earlier, I tried putting the getRed, getGreen, and getBlue in a for loop but it only shows the same RGB value. How do I get all the RGB values in an image? Given that I wanna store them in different arrays.
I'm not entirely clear on the question, but assuming you mean unique RGB values, just loop, and just use say java.util.Set implementation that maintains uniqueness?
Set<Color> colors = new HashSet<Color>();
for (int datum : dataBuffInt) {
colors.add(new Color(datum));
}
System.out.println(String.format("%d different colors", colors.size()));
Or if you mean separate components?
for (int datum : dataBuffInt) {
Color color = new Color(datum);
reds.add(color.getRed());
greens.add(color.getGreen());
blues.add(color.getBlue());
}
System.out.println(String.format("reds: %d greens: %d blues: %d", reds.size(), greens.size(), blues.size()));
Are you certain when you had the for loop you were using the index variable into the array and not a static value, like 100? When I run your code with a for loop I see different values:
for (int i = 0; i < dataBuffInt.length; i++) {
Color c = new Color(dataBuffInt[i]);
System.out.println("COLOR");
System.out.println(c.getRed()); // = (dataBuffInt[100] >> 16) & 0xFF
System.out.println(c.getGreen()); // = (dataBuffInt[100] >> 8) & 0xFF
System.out.println(c.getBlue()); // = (dataBuffInt[100] >> 0) & 0xFF
System.out.println(c.getAlpha()); // = (dataBuffInt[100] >> 24) & 0xFF
System.out.println();
}
If you want unique colors you could build a set one pixel at a time:
final BufferedImage image = ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/en/2/24/Lenna.png"));
final Set<Color> uniqueColors = new HashSet<Color>(image.getWidth() * image.getHeight());
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
final int rgb = image.getRGB(x, y);
uniqueColors.add(new Color(rgb));
}
}
for (final Color color : uniqueColors) {
System.out.println(format("red: {0}, green: {1}, blue: {2}, alpha: {3}",
color.getRed(),
color.getGreen(),
color.getBlue(),
color.getAlpha()));
}
Or use your existing code and dump the array into a set.

Incorrect result of image subtraction

I wanted to subtract two images pixel by pixel to check how much they are similar. Images have the same size one is little darker and beside brightness they don't differ. But I get those little dots in the result. Did I subtract those two images rigth? Both are bmp files.
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class Main2 {
public static void main(String[] args) throws Exception {
int[][][] ch = new int[4][4][4];
BufferedImage image1 = ImageIO.read(new File("1.bmp"));
BufferedImage image2 = ImageIO.read(new File("2.bmp"));
BufferedImage image3 = new BufferedImage(image1.getWidth(), image1.getHeight(), image1.getType());
int color;
for(int x = 0; x < image1.getWidth(); x++)
for(int y = 0; y < image1.getHeight(); y++) {
color = Math.abs(image2.getRGB(x, y) - image1.getRGB(x, y));
image3.setRGB(x, y, color);
}
ImageIO.write(image3, "bmp", new File("image.bmp"));
}
}
Image 1
Image 2
Result
The problem here is that you can't subtract the colors direcly. Each pixel is represented by one int value. This int value consists of 4 bytes. These 4 bytes represent the color components ARGB, where
A = Alpha
R = Red
G = Green
B = Blue
(Alpha is the opacity of the pixel, and always 255 (that is, the maximum value) in BMP images).
Thus, one pixel may be represented by
(255, 0, 254, 0)
When you subtract another pixel from this one, like (255, 0, 255, 0), then the third byte will underflow: It would become -1. But since this is part of ONE integer, the resulting color will be something like
(255, 0, 254, 0) -
(255, 0, 255, 0) =
(255, 255, 255, 0)
and thus, be far from what you would expect in this case.
The key point is that you have to split your color into the A,R,G and B components, and perform the computation on these components. In the most general form, it may be implemented like this:
int argb0 = image0.getRGB(x, y);
int argb1 = image1.getRGB(x, y);
int a0 = (argb0 >> 24) & 0xFF;
int r0 = (argb0 >> 16) & 0xFF;
int g0 = (argb0 >> 8) & 0xFF;
int b0 = (argb0 ) & 0xFF;
int a1 = (argb1 >> 24) & 0xFF;
int r1 = (argb1 >> 16) & 0xFF;
int g1 = (argb1 >> 8) & 0xFF;
int b1 = (argb1 ) & 0xFF;
int aDiff = Math.abs(a1 - a0);
int rDiff = Math.abs(r1 - r0);
int gDiff = Math.abs(g1 - g0);
int bDiff = Math.abs(b1 - b0);
int diff =
(aDiff << 24) | (rDiff << 16) | (gDiff << 8) | bDiff;
result.setRGB(x, y, diff);
Since these are grayscale images, the computations done here are somewhat redundant: For grayscale images, the R, G and B components are always equal. And since the opacity is always 255, it does not have to be treated explicitly here. So for your particular case, it should be sufficient to simplify this to
int argb0 = image0.getRGB(x, y);
int argb1 = image1.getRGB(x, y);
// Here the 'b' stands for 'blue' as well
// as for 'brightness' :-)
int b0 = argb0 & 0xFF;
int b1 = argb1 & 0xFF;
int bDiff = Math.abs(b1 - b0);
int diff =
(255 << 24) | (bDiff << 16) | (bDiff << 8) | bDiff;
result.setRGB(x, y, diff);
You did not "subtract one pixel from the other" correctly. getRGB returns "an integer pixel in the default RGB color model (TYPE_INT_ARGB)". What you are seeing is an "overflow" from one byte into the next, and thus from one color into the next.
Suppose you have colors 804020 - 404120 -- this is 3FFF00; the difference in the G component, 1 gets output as FF.
The correct procedure is to split the return value from getRGB into separate red, green, and blue, subtract each one, make sure they fit into unsigned bytes again (I guess your Math.abs is okay) and then write out a reconstructed new RGB value.
I found this which does what you want. It does seem to do the same thing and it may be more "correct" than your code. I assume it's possible to extract the source code.
http://tutorial.simplecv.org/en/latest/examples/image-math.html
/Fredrik Wahlgren

BufferedImage - getting the value of a pixel in grayscale color model picture

I have an BufferedImage transformed to grayscale using this code. I usually got the pixel values by BufferedImage.getRGB(i,j) and the gor each value for R, G, and B. But how do I get the value of a pixel in a grayscale image?
EDIT: sorry, forgot abou the conversion.
static BufferedImage toGray(BufferedImage origPic) {
BufferedImage pic = new BufferedImage(origPic.getWidth(), origPic.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
Graphics g = pic.getGraphics();
g.drawImage(origPic, 0, 0, null);
g.dispose();
return pic;
}
if you have RGB image so you can get the (Red , green , blue , Gray) values like that:
BufferedImage img;//////read the image
int rgb = img.getRGB(x, y);
int r = (rgb >> 16) & 0xFF;
int g = (rgb >> 8) & 0xFF;
int b = (rgb & 0xFF);
and the gray is the average for (r , g , b), like this:
int gray = (r + g + b) / 3;
but if you convert RGB image(24bit) to gray image (8bit) :
int gray= img.getRGB(x, y)& 0xFF;/////////will be the gray value

convert int color to int components

I obtain pixel color by
int color = image.getRGB(x,y);
then i want to acquire red, green, blue components separately. How to do that? Maybe using some bitmask?
int green = color&0x00ff00;
apparently not working... :(
To get color components you can use:
import android.graphics.Color;
int r = Color.red(intColor);
int g = Color.green(intColor);
int b = Color.blue(intColor);
int a = Color.alpha(intColor);
int value = image.getRGB(x,y);
R = (byte)(value & 0x000000FF);
G = (byte)((value & 0x0000FF00) >> 8);
B = (byte)((value & 0x00FF0000) >> 16);
A = (byte)((value & 0xFF000000) >> 24);
May need to flip the R, A, or B around.
You forgot to shift the byte to the right:
int green = (color & 0x00ff00) >> 8;
You can use Color constructor and pass the given integer and hasalpha=true:
Color color = new Color(image.getRGB(x,y), true);
getRGB returns the color of type TYPE_INT_ARGB which means it has an alpha channel.

Categories