I'm trying to determine if an image is a black and white image, or if it has color (using Java). If it has color, I need to display a warning message to the user that the color will be lost.
Any suggestion for me?
It is possible. You can load images with ImageIO.
BufferedImage img = ImageIO.read(imageFile);
int rgb = img.getRGB(x,y);
Color color = new Color(rgb);
But still you need to create an algorithm that finds x,y bounds and check color of each location.
ImageIO will allow you to load the image, as someone else mentioned.
An optimization is possible which will help in a lot of cases: If the image is grayscale to begin with - as in, the file format says "this is a grayscale image", you can detect that using img.getColorModel().getColorSpace() to determine if you have an image whose color space only includes shades of gray.
For indexed color palettes (GIF files, for instance), you can iterate all of the colors in the color model and quickly determine if any have color (if the red/green/blue values are identical, there is no color).
For the rest, you'll have to sample pixels from the image (use some pattern to walk the image that skips around between positions so you don't spend a lot of time on black/white/gray borders before encountering color) and do something like
Color c = new Color(img.getRGB(x,y));
boolean isGray = c.getRed() == c.getGreen() && c.getRed() == c.getBlue();
...
At some size of image, it may become too expensive to iterate every pixel of the image to detect if even a single colored pixel exists, and you may want to assume there is some color and warn the user always.
Related
I was wondering whether or not you could apply a tint to a colored image to make a black and white version of that image. For example, having a landscape, applying a tint, and the new photo being only black and white. I'm dealing with an image that I cannot directly change the RGB pixel values for, which is why my only option is to overlay something on top of it. I attempted some Google searches, but to no avail, and unfortunately, I'm not an expert in color theory.
In essence, I'm looking for something that would accomplish this for any color:
COLOR + MAGIC VALUE = GRAY-SCALED (desaturated) COLOR
To be clear, 'magic value' is the color that I hope exists. Any help would be much appreciated!
TL;DR
There is no magic colour value that will do this for you.
The long version
Let's assume that the grayscale value for a pixel is equivalent to the average values of R, G and B.
If we represent the colour of a pixel as {R,G,B} and let's say you have a 2x2 image:
{10,20,30} {30,50,70}
{90,70,80} {90,130,110}
.. and you want to convert this to:
{20,20,20} {50,50,50}
{80,80,80} {110,110,110}
The magic values would need to be:
{10,0,-10} {20,0,-20}
{-10,10,0} {20,-10,0}
As shown, this magic colour value has to be different for each pixel (but can be calculated from the original image).
I have two RenderedImages. I want to do an Overlay Operation with these two images and therefore they need to match in data type and the number of bands.
The problem I have is that one image has 3 bands (RGB) and the second image has 4 bands (ARGB).
My question is how can I add an Alpha Channel to the first image so I can do the Overlay Operation?
EDIT
Ok, I found a method of adding an Alpha Channel to the first image. Below is the code. I simply created a single banded constant image and merged it with my first image.
ParameterBlock pb = new ParameterBlock();
pb.add(new Float(finalImage.getWidth())).add(new Float(finalImage.getHeight()));
pb.add(new Byte[] {new Byte((byte)0xFF)});
RenderedImage alpha = JAI.create("constant", pb);
finalImage = BandMergeDescriptor.create(finalImage, alpha, null);
The problem I have now is that everytime I add an overlay the image changes colors. All the colors become nuances of red or pink. When I add a second overlay, the image becomes normal again, but the first overlay changes colors. All black areas become white.
Also the background of the overlay is not transparent. It is grey.
Below are examples of the images, so you see how the change colors:
As you can see, the picture and overlays change colors and the background of the overlay isn't transparent.
Can you help me solve this problem, so that the image is always displayed correctly? Thanks!
You can try to create a new BufferedImage with ARGB-model, and just paint the non-transparent background picture into this new BufferedImage. Then you have a BufferedImage with alpha-channel (although all of the pixels are opaque), so the Composition should hopefully work.
im not sure about TYPE_4BYTE_ARGB as I usually work with BufferedImages of TYPE_INT_ARGB but I have often used the method of drawing a RGB BufferedImage to a new ARGB BufferedImage and then drawing that onto other things without problem. the change in color would suggest an unwanted change is being made to the other channels in the overlay process as it doesn't seem to be specific to a specific image. If your overlay operation is similar to drawing one image onto another with alpha I would probably suggest using the Graphics.drawImage()/drawRenderedImage() method for the overlay itself not to mention the background should not even need alpha in this case.
the code:
public RenderedImage overlay(RenderedImage back, RenderedImage front, AffineTransform overlayTransformation)
{
BufferedImage newBack = new BufferedImage(back.getWidth(), back.getHeight(), TYPE_3BYTE_RGB);
newBack.setData(back.getData());
Graphics2D graphics = (Graphics2D)(newBack.getGraphics());
graphics.drawRenderedImage(front, overlayTransformation);
return newBack;
}
you may want to ensure the original back Raster is not modified though.
I am currently working with a DICOM project in java. I am calculating the dicom values such as depth, off-axis ratio, width and height. I want to create a sample image with the calculated width and height. I should be a gray scale image, with varying densities of gray color in appropriate area. I have created a sample image with imagemagick, using concentric circles. Bit am not getting the exact image. It does not look like an actual dicom image. The variation of gray color does not have a linear behavior. Sample image is attached. Please suggest any other method to create dicom image. The density values are available in a list. depending upon the distance from the center, the gray color also changes according to the density value provided.
Pixel Data or image in DICOM data set is always rectangular and image is described using Rows (0028, 0010) and Columns (0028, 0011) attributes. So the best way to implement this is to draw your circular image on a rectangular background. Fill the background with a color that is not present in your image. Use the Pixel Padding Value (0028,0120) to specify the color used to pad grayscale images (those with a Photometric Interpretation of MONOCHROME1 or MONOCHROME2) to rectangular format.
If you do not have any color to spare (with-in the bit stored), you can add Overlay Plane or Display Shutter to the data set to mask the area that is not part of image.
I want to inset a image into a background and save it, both are png files with transparency, below code work fine but new image become black & white only.
BufferedImage BUFFEREDIMAGE1=ImageIO.read(new File(strPATH+"/IMAGE.png"));
BufferedImage BUFFEREDIMAGE2=ImageIO.read(new File(strPATH+"/WATERMARK.png"));
Graphics2D GRAPHICS1=BUFFEREDIMAGE1.createGraphics();
GRAPHICS1.drawImage(BUFFEREDIMAGE2,intLeft,intTop,intWidth,intHeight,null);
GRAPHICS1.dispose();
ImageIO.write(BUFFEREDIMAGE2,"png",new File(strPATH,"SAVED.png"));
The most likely cause is that at some point the colour space of the image is becoming changed. You may be better off explicitly creating a new destination BufferedImage with the RGB or RGBA format and writing both source Images into it. This removes any possible variation in that area.
I am trying to determine an image's color space in Java. I believe this is referred to as "imageType" in the BufferedImage class. This is the line of code which causes me trouble - I don't know what to put as the third argument:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
I'm going to stitch several images together into the BufferedImage using the class Graphics2D. Some images I use may be in RGB format, others in ARGB, 4-byte ARGB etc...
Is there any way I can programatically determine the color spaces of the images? Or if not, is there a way of converting all images into the same color space before stitching?
The ColorConvertOp class can be used to convert an image from one ColorSpace to another.
BufferedImage.getType() can be used to determine the color space used by the image.