Convert 2D array of integers to bitmap in Java - java

I have a 2D array of integers in Java.
I want to take this and output a bitmap image file where the red value of each pixel is the corresponding value in the array (blue and green values are 0).
Does anyone know how to do this? Thanks.

You can create a BufferedImage and use BufferedImage.setRGB(x, y, rgb), where rgb is your (byteArray[x][y] <<< 4) & 0xFF0000. Then save it using ImageIO.write(image, "bmp", file).

There nothing to do but to do it, unfortunately. That's not supposed to be a flip answer - but the file format for a BMP image, which is the easiest, is well defined.
Here's the BMP wiki.

Related

Mask image in opencv java

I need to convert near white pixels to white and near black pixels to black.
I found a code snippet in python on how to do it.
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
# Define lower and upper limits of what we call "brown"
brown_lo=np.array([10,0,0])
brown_hi=np.array([20,255,255])
# Mask image to only select browns
mask=cv.inRange(hsv,brown_lo,brown_hi)
# Change image to red where we found brown
image[mask>0]=(0,0,255)
I have converted it java as below.
Mat temp= new Mat();
Imgproc.cvtColor(src,temp,COLOR_BGR2HSV);
Scalar low= new Scalar(10,0,0);
Scalar high= new Scalar(20,255,255);
Mat mask = new Mat();
inRange(temp,low,high,mask);
But I am facing problem converting below statement to java and there is no good opencv documentation in java with samples.
image[mask>0]=(0,0,255)
Could somebody help on how to convert above statement to java...?
I have tried setTo but it is not giving desired behaviour(attached screenshot below). Refer https://stackoverflow.com/a/50215020/12643143 for the expected result.
src.setTo(new Scalar(0,0,255),mask);
I recommend to use setTo(). This method can set all he pixels in a Mat. If an optionally mask argument is specified, then all the pixels who have a corresponding pixel with a non-zero value in the mask will be set.
Thus the python statement
image[mask>0]=(0,0,255)
can be substituted in Java by:
image.setTo(new Scalar(0, 0, 255), mask);
where image has to be a Mat object.
Answer to the question
As #Rabbid76 mentioned setTo is the correct way to do this. However if you want specific logic like image[mask>127]=(0,0,255), then do threshold (Imgproc.threshold(grey,grey, 127, 255, THRESH_BINARY);) and then use setTo.
Solution to my problem
Actually my problem was not due to setTo. Its the logic mismatch between how I read/write the Mat in my code Vs the post I referred.
I am posting the solution to the problem that I have faced so that it might help new bees like me.
Problem in reading Image
The post use Imgcodecs.imread() to read image to Mat in BGR format.
Whereas I am loading bitmap using bitmapToMat in CV_8UC4 type as below which reads the image to Mat in RGBA format.
Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CV_8UC4);
org.opencv.android.Utils.bitmapToMat(bitmap, src);
Fix is to convert the format properly.
Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CV_8UC3); //notice 3 channel
org.opencv.android.Utils.bitmapToMat(bitmap, src);
Imgproc.cvtColor(src,hsv,COLOR_RGB2HSV); //Convert RGB to HSV. COLOR_RGBA2HSV not exist, hence we load it in CV_8UC3(3 channel R,G,B).
Problem in writing the Image
Similarly as we have differences in reading between bitmapToMat and imread, the same are applicable for writing. Imgcodecs.imwrite() will write the BGR image to bitmap, where as I have to convert it back to RGB format for matToBitmap to work like Imgproc.cvtColor(rgb, rgb, Imgproc.COLOR_BGR2RGB);

Java - reading a compressed bitmap

I'm looking to read in the RGB values of a bitmap (or the hex colour codes, either work).
I have tried both this code :
File image = serverConfig.get(map.bmp);
BufferedImage buffer = ImageIO.read(image);
dimX = buffer.getWidth();
dimY = buffer.getHeight();
byte[] pixlesB = (byte[]) buffer.getRaster().getDataElements(0, 0, buffer.getWidth(), buffer.getHeight(), null);
and this code :
File image = serverConfig.get(map.bmp);
BufferedImage buffer = ImageIO.read(image);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(buffer, "bmp", baos );
baos.flush();
byte[] pixlesB = baos.toByteArray();
baos.close();
The both work fine for a small bitmap, but when I load a large bitmap, the data gets compressed and the array returns a bunch of semi random numbers.
for example:
A green pixel will read 2,2,2 instead of 0,255,0
A red pixel will read 5,5,5 instead of 255,0,0
A yellow pixel will read 8,8,8 instead of 255,255,0
The bitmaps I'm using only include the colours red, yellow and green.
My problem is I have no way of knowing what colour 2,2,2 relates to without checking it manually (which I cannot do since it changes with each bitmap)
I know that there is some metadata in the bitmap that specifies 2 is green, but I don't know how to access it or use it to turn 2 back into 0,255,0
And this is not a duplicate of Java - get pixel array from image since that doesn't mention compressed files.
And while I did ask this question a while back, it was just redirected to the above site.
Thanks in advance!
EDIT: Just thought this might make the question a bit clearer. I believe the file is being read correctly, it is just compressed. How do I decompress it?
If you want to read an image as a bitmap or as rgb values, you need to transform the image's format first.
Jpeg is a compressed image format, you need to use a tool or library in order to read as rgb.
check this answer:
How to get the rgb values of a jpeg image in TYPE_3BYTE_BGR?
Hope this helps

converting an image format with ImageJ

I have the following code that I use to convert an image from fits format to jpeg format
ImagePlus fitsImage = openImage(fitsImagePath);
final File out = new File(fullPath + fileNameNoExt + ".jpg");
BufferedImage jpgImage = fitsImage.getBufferedImage();
ImageIO.write(jpgImage, "jpg", out);
the actual format change is working and I do get a jpg file, but the problem is that the resulting file is in black and white and I know for a fact that the image I am using is colored.
So the question is what should I do to make the resulting image colored.
cheers,
es
For some reason the getBufferedImage() function is only copying the data in an 8-bit format. As I am unfamiliar with fits format, what pixel depth does it have and what pixel depth does your data have?
If you are importing in 8-bit which is false colored with red, green, or blue, then when you export it will maintain its 8-bit grey scale and not the false color.
If you want it to maintain its rgb, you will have to convert it into a rgb format before exporting.
The function command flatten might help as it will convert the picture to an RGB format
fitsImage.flatten()

How can I know if the image is in RGB or BGR format?

Is there any way to know in advance if an image used as an input to a system is in RGB or BGR format?
I am using OpenCV with java API and I would like to convert an input image into grayscale or L*a*b* color space, but in OpenCV you have to specify first whether the image you want to convert is in RGB or BGR.
The type of the image I am using is either .jpg or .png.
If you are reading in the image file, or you have access to the code that reads in the file, know it is:
BGR order if you used cv2.imread()
RGB order if you used mpimg.imread() (assuming import matplotlib.image as mpimg)
If you don't know how the file was opened, the accepted answer BufferedImage is great for Java.
I would like to find a way to do the same in Python!
When you use opencv (imread, VideoCapture), the images are loaded in the BGR color space.
If your image is a BufferedImage then you can ask for his type with getType(), and test against the several constants (see: BufferedImage).

how to know if the image is 32-Bit ,24-Bit ,8-Bit , 1-Bit in each pixel

I am posting this question after a lot of Google searching
I want to convert an image to array of bits , but my research guide to know that for each image the pixel in it could be 32 bit or 24 bit ... etc
So how to know the number of bits for the pixel in each image ?
You need use javax.ImageIO API
ColorModel color = ImageIO.read(new File("test.jpg")).getColorModel();
color.getPixelSize();
If you have a java.awt.image.RenderedImage, you can call getData to get the rasterised data for that image.
This is essentially a pixel-by-pixel plot of the data, and indeed you can call getPixel(int x, int y, double[] dArray) to get an array of the data for a single given pixel.

Categories