getRGB() returning different value after setRGB() - java

I want to extract the pixel values from a jpeg image using getRGB(). But the problem is that the getRGB() method returns different values each time I invoke the method after setRGB(). After going through some solutions over the internet, many suggested to use .png images instead of .jpg. Now, is there a way to extract the pixel value ranging between 0-255 from a jpg image ?

Related

pixel's exact value from a JPG image in java

does anyone know how can I get the exact values from JPG image, for example: I have created an image that only contains values from 0 - 255, this image is on gray scale, that means : RGB values are exactly the same. In the other hand I exactly know the value from each pixel in each position, but when I use the getRGB() Im gettin values that does not match with the original values. Eg:
I have a '0' in the position [0][0] the getRGB() is returning a decimal number '13'; in the next position [0][1] I have a '1' but the getRGB() is returning a decimal number '13' too... So guys I know that these values can be because of the compression of the image. But anyone has an idea of what adjust I can make to get the correct values???
I will appreciate any help..
JPEG uses lossy compression algorithm: it sacrafices data precision to achieve better compression. So you can't get back the exact RGB values.
If you need to get back the exact RGB values, use PNG image format which uses lossless compression algorithms.
Also BufferedImage.getRGB() returns the pixel data quoting from the javadoc:
Returns an integer pixel in the default RGB color model (TYPE_INT_ARGB) and default sRGB colorspace.
So if you have gray values in the range of 0..255, the RGB values returned by getRGB() will be in the range of 0...16777215 (16777215=0xffffff). The int returned by getRGB() is not the gray version but contains the RGB components (and the alpha if it has transparency).

Do certain image file types always correspond with certain BufferedImage constant types?

The BufferedImage class in Java contains a getType() method which returns an integer correlating with a BufferedImage constant type variable describing some information about how the image is encoded (you can look at the BufferedImage source to determine what number corresponds to what constant type variable). For instance, if it returns the integer corresponding with BufferedImage.TYPE_3BYTE_BGR, then that means that the BufferedImage is an 8-bit RGB image with no alpha and with blue, green, and yellow each being represented by 3 bits.
Some of these image types seem to correlate with certain properties of a particular format. For instance, TYPE_BYTE_INDEXED says that it is created from "a 256-color 6/6/6 color cube palette". This sounds a lot like GIF images, which are created from 256 colors.
Curious, I scanned several hundred photos on my hard drive and converted each of them to a BufferedImage, using ImageIO.read(File file), then called BufferedImage.getType() on them. I determined that there were only a few BufferedImage types that were generated from certain image types. The results were as follows:
JPG: TYPE_3BYTE_BGR, TYPE_BYTE_GRAY
PNG: TYPE_3BYTE_BGR, TYPE_BYTE_GRAY, TYPE_4BYTE_BGRA
GIF: TYPE_BYTE_INDEXED
While it looks like both JPGs and PNGs shared some similar BufferedImage constant types, only a PNG in my test resulted in a TYPE_4BYTE_BGRA and every GIF resulted in a TYPE_BYTE_INDEXED.
I'm not too familiar with image formats and it's true that my sample size isn't all that large. So I figured I'd ask: assuming that an image is properly formatted, do certain image types always result in BufferedImages with certain constant types? To provide a specific example, would a properly formatted GIF image always correspond to TYPE_BYTE_INDEXED? Or is it possible for all properly formatted images to correspond with all of the BufferedImage constant types?
[Do] certain image types always result in BufferedImage with certain constant types?
As in in your other question; No, there is no direct relationship between the BufferedImage types and file formats.
Or is it possible for all properly formatted images to correspond with all of the BufferedImage constant types?
Basically, yes. Of course, a color image would lose information if converted to gray,
a 16 bit per sample image would lose precision if converted to 8 bits per sample, etc.
However, different file formats have different ways of storing pixels and colors, and usually a certain BufferedImage type more closely represent the "layout" used in the file format.
Let's use your GIF example:
The storage "layout" of a GIF (before applying LZW compression) is normally closest to that of TYPE_BYTE_INDEXED, so that is usually the "cheapest" conversion to do in Java. For GIFs with up to 16 colors, TYPE_BYTE_BINARY would work just as well. And it's always possible for a GIF to be decoded into TYPE_4BYTE_ABGR or TYPE_INT_ARGB (or even TYPE_3BYTE_BGR or TYPE_INT_RGB if no transparent color).
In other words, the type of image depends on the decoder, and in some cases (like for the ImageIO API) the user.
To summarize, what you have found, is that the GIF plugin for ImageIO (GIFImageReader) by default will decode a GIF with more than 16 colors to TYPE_BYTE_INDEXED. Using a different decoder/framework may yield different results.
A little bit of history that might enlighten the curious reader:
The types of BufferedImages where not modeled to correspond to image formats. They were modeled to correspond to display hardware. An image having the same pixel layout as the display hardware is always going to be faster to display. Other layouts would first need to go through some kind of conversion. Now with modern display hardware being very fast, this is of course less of a concern, but in "ancient" times this was important.
Incidentally, many "ancient" image formats were created ad hoc, or for specific applications running on specific display hardware. Because of this, the pixel layout of the display hardware were often used in the file format. Again, because no conversion was needed, and it was the fastest/simplest thing to implement.
So, yes, there is a relationship. It's just not a direct "given A => B" relationship, it's a "given A and C => B".

How to convert an indexed image to a RGB image in Java?

I have a color indexed TIFF image (8-bits) and I want to convert it to a RGB 24-bits image (not indexed). What would be the way to do that?
I'm using JMagick. In a weird way, it works fine for indexed 8-bits images that are grayscale when i use:
image.transformRgbImage(info.getColorspace());
even if the image, though not indexed any more, is still 8-bits after that, which is lucky as it is grayscale and should actually be 8-bits. The weird stuff is that the transformRgbImage() performs that although I'd rather expect it to convert the image to a 24-bits one. Anyway...
The same way doesn't work for a color indexed 8-bits image. I just don't know how to use the JMagick API to achieve that goal. I tried setting:
image.setDepth(24);
or:
info.setDepth(24);
but both result in an EXCEPTION_ACCESS_VIOLATION. When I set:
info.setDepth(32);
no exception is raised, 1) but the image is 32-bits, which shouldn't be, and 2) it is all black (1 unique color). Why does the setDepth(24) raises such an exception?? How should I do?
Thanks in advance for your help.
I dont know about jmagick, but generally once you created an image object its properties are fixed (size and color model).
You don't change an images properties, you create a new image with the desired target properties and paint your original image into the new image. In plain core java you would simply do it like this:
public BufferedImage toRGB(Image i) {
BufferedImage rgb = new BufferedImage(i.getWidth(null), i.getHeight(null), BufferedImage.TYPE_INT_RGB);
rgb.createGraphics().drawImage(i, 0, 0, null);
return rgb;
}

BufferedImage to array

What are the advantages of converting a buffered image into an array of integers?I assume that i can manipulate the array and cross process the picture .Is that so?
I think you are referring to getRgb() method of BufferedImage class.
Supposing you want to modify the whole image or a big portion of it, retrieving the pixel array, and perform operations on it could be considerely faster than accessing each single pixel through method calls such as setRgb().
SwingX introduces the AbstractFilter class for BufferedImage. Here is an example:
http://www.jarvana.com/jarvana/view/org/swinglabs/swingx/0.9/swingx-0.9-sources.jar!/org/jdesktop/swingx/image/GaussianBlurFilter.java?format=ok
For simple editing use one of this examples:
http://www.exampledepot.com/egs/java.awt.image/imagepixel.html
Buffered image pixel manipulation
How do I create a BufferedImage from array containing pixels?
Having a BufferedImage into memory as an array of int values could help you apply filters on the image by processing the int values into memory and then setting the result back to another BufferedImage.

Android image strip and edit / combine 2 pictures

I want to create an android app that takes 2 pictures (taken from the phone camera). Takes the top part of pic1 and the bottom part of pic2 and combines them to the final picture.
I'm thinking about converting each image to byte array. Then take the half values from the array of the first image and the other half from the other image, merge them in the final array and convert that array back to image. Is it feasible? Is this a good solution or there is any better practice for this?
Well I guess I found the solution. There is a class in the Java6 API called "BufferedImage". This class has the methods: setRGB , getRGB where you can get the int value of the rgb color for the pixel you specify. This way you can get the pixel color from the image you want and set it in the target image.
Try using OpenCV. It will be very fast since it will be handling the images in native code. Convert Bitmap objects into Matrix(OpenCV) object and send the address to the native code where you can do these computations very easily. If any code is required, do let me know.

Categories

Resources