I am having an image file downloaded as byte array inside my java method. Need to convert this byte array into BufferedImage.
InputStream inputStream = new ByteArrayInputStream(imagebyteArray);
BufferedImage originalImage = ImageIO.read(inputStream);
ImageIO.write(originalImage, "jpg", new File("/Users/abc/test.jpg"));
Above code snippet is used to convert the image byte array and write into jpeg file. But I am getting a zero sized image file.
But issue with the downloaded image. Image is actually JPEG format but the extension is wrong like image.doc
Is it a problem ? , if that is an issue Is there any way to convert the extension of the image (byte array) using java2d , and then convert to BufferedImage?
Related
I used this Tutorial to learn and try understand how to make a simple picture taking android app using the Camera2 API. I have added some snippets from the code to see if you all can help me understand some questions I have.
I am trying to find out how the image is saved as. Is it RGB, or BGR?
Is it stored in the variable bytes?
ImageReader reader = ImageReader.newInstance(width,height,ImageFormat.JPEG, 1);
#Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
}
The image is received in JPEG format (as specified in the first line). Android uses YUV (to be more exact, YCbCr) color space for JPEG. Jpeg size is variable, it is compressed with lossy compression, and you have very little control over the level of compression.
Normally, you receive a JPEG buffer in onImageAvailable() and decode this JPEG to receive a Bitmap. You can get pixels of this Bitmap as an int array of packed SRGB pixels. The format for this array will be ARGB_8888.
You don't need JNI to convert it to BGR, see this answer.
You can access Bitmap objects from C++, see ndk/reference/group/bitmap. There you can find the pixel format of this bitmap. If it was decoded from JPEG, you should expect this to be ANDROID_BITMAP_FORMAT_RGBA_8888.
The variable bytes contains an entire compressed JPEG file. You need to decompress it to do anything much with it, such as with BitmapFactory.decodeByteArray or ImageDecoder (newer API levels).
It's not an uncompressed array of RGB values in any sense. If you want uncompressed data, the camera API supports the YUV_420_888 format, which will give you uncompressed 4:2:0 YUV data; still not RGB, though.
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
I am reading an grayscale tiff image into inputstream using
InputStream is=objCMBObject.getDataStream();
bytes = IOUtils.toByteArray(is);
response.setContentType(mimeType);
OutputStream os = response.getOutputStream();
and writing this stream into applet .but now I want to convert this grayscale image to binary image before writing to the applet. I don't want to save the image in file.
How to convert inputstream of grayscale to binary?
I can convert the image into binary if I have x,y coordinates but I don't know how to get it from inputstream.
Please guide.
When you want to manipulate an image, javax.imageio.ImageIO can be of great use. You can use that to load the image from the stream, apply some operation like a ColorConvertOp, and write the result back to a stream.
As ImageIO doesn't neccessarily support TIFF out of the box, you might have to use a suitable library to provide TIFF support. Answers to another question suggest using Java Advanced Imaging for this.
i am using LibJpeg library for decoding jpeg image ( given in form of byte array ) into rgb color map .
but it come different from my sample output i want to check by java programme .
how to do this in by java programme ?
what is use of APPn in header ?
how to decode jpeg image into rgb pixel .
Why not use ImageIO.read together with ByteArrayInputStream to read the byte array into an image then no extra library is needed (pure java solution):
BufferedImage image = ImageIO.read(new ByteArrayInputStream(bytes));
I have a servlet based application that is serving images from files stored locally. I have added logic that will allow the application to load the image file to a BufferedImage and then resize the image, add watermark text over the top of the image, or both.
I would like to set the content length before writing out the image. Apart from writing the image to a temporary file or byte array, is there a way to find the size of the BufferedImage?
All files are being written as jpg if that helps in calculating the size.
BufferedImage img = = new BufferedImage(500, 300, BufferedImage.TYPE_INT_RGB);
ByteArrayOutputStream tmp = new ByteArrayOutputStream();
ImageIO.write(img, "png", tmp);
tmp.close();
Integer contentLength = tmp.size();
response.setContentType("image/png");
response.setHeader("Content-Length",contentLength.toString());
OutputStream out = response.getOutputStream();
out.write(tmp.toByteArray());
out.close();
No, you must write the file in memory or to a temporary file.
The reason is that it's impossible to predict how the JPEG encoding will affect file size.
Also, it's not good enough to "guess" at the file size; the Content-Length header has to be spot-on.
Well, the BufferedImage doesn't know that it's being written as a JPEG - as far as it's concerned, it could be PNG or GIF or TGA or TIFF or BMP... and all of those have different file sizes. So I don't believe there's any way for the BufferedImage to give you a file size directly. You'll just have to write it out and count the bytes.
You can calculate the size of a BufferedImage in memory very easily. This is because it is a wrapper for a WritableRaster that uses a DataBuffer for it's backing. If you want to calculate it's size in memory you can get a copy of the image's raster using getData() and then measuring the size of the data buffer in the raster.
DataBuffer dataBuffer = bufImg.getData().getDataBuffer();
// Each bank element in the data buffer is a 32-bit integer
long sizeBytes = ((long) dataBuffer.getSize()) * 4l;
long sizeMB = sizeBytes / (1024l * 1024l);`
Unless it is a very small image file, prefer to use chunked encoding over specifying a content length.
It was noted in one or two recent stackoverflow podcasts that HTTP proxies often report that they only support HTTP/1.0, which may be an issue.
Before you load the image file as a BufferedImage make a reference to the image file via the File object.
File imgObj = new File("your Image file path");
int imgLength = (int) imgObj.length();
imgLength would be your approximate image size though it my vary after resizing and then any operations you perform on it.