How can I read the metadata from bitmaps in Android (Java)? - java

How can I read the file format (png, jpg, gif, bmp, tiff, etc) and the width, height, and for those that have the value, the DPI for a bitmap?
Android does not have javax.imageio.* so the standard Java calls to read this are not available. metadata-extractor is a good product but does not support png or gif.

Width and height, along with bitdepth and color model, are not usually considered "metadata", rather they are basic image properties. By "image metadata" we usually refer to less essential data like physical resolution (DPI), EXIF-like data (timestamp, camera model, etc), etc; these are relatively format specific.
If you have decoded a image file (PNG, JPEG, GIF...) into a Bitmap, then you can ask the Bitmap object for the basic properties (eg, getHeight()).
But if you need to ask for some "metadata", which is format specific, a Bitmap object won't store that information, you need something like the metadata-extractor you linked.
For PNG, you can also use this library (my own).

Related

Extract image into a file from PDImageXObject without loading it into memory

This is related to How to extract image bytes out of PDF efficiently, but I'll try to restate the problem differently so it's less about PDF parsing and more about image processing.
I'm using PDFBox to extract images out of PDF files. There's an class PDImageXObject that represents the image inside the PDF, which contains image metadata (height, width, etc), and exposes two APIs to pull out the image are: BufferedImage getImage() and BufferedImage getImage(Rectangle rect, int subsampling);.
The current code is straightforward:
BufferedImage image = pdImage.getImage();
ImageIO.write(image, "jpg", baos);
However, for a large image, I'm having an issue with memory usage, as BufferedImage is storing uncompressed image data in memory, which is a lot bigger than the compressed result.
Is there a way to avoid loading the whole image into memory by breaking it up into tiles (e.g. 1024x1024) and iterating over them using the getImage signature that takes Rectangle? I'm seeing some promising information about JAI being able to use Tiles to output a compressed image without loading the uncompressed content into memory at once, but I don't understand how to tie it together with what I have from PDImageXObject. Or is there another way to do it? Is JAI still an active project?
By the way, the purpose of extracting the image is to feed it into the next component in the pipeline that can handle multiple image formats. So, if some format other than jpg, is more suited for tiled processing, that should be ok.
I'm aware of one possibility using something like BigBufferedImage. But I was thinking processing a Tile at a time looked promising.
OK, I found a libray: Commons Imaging. Class Imaging maybe can help you.
I think you can try createInputStream() method, find out the size of real data(bytes length).

Modify image data in ByteBuffer

I would like to modify the per-pixel RGB color data of a PNG image that I have loaded as a ByteBuffer, preferably a simple, lightweight solution.
I currently load the data directly from the file into a ByteBuffer using a ReadableByteChannel, which does not decode the PNG data.
So the question is, how do I
Decode the ByteBuffer PNG data into something where I can modify the pixel data
Turn it back into a valid ByteBuffer ('valid' means that it would be accepted by an OpenGl shader)
The PNG image encoding includes (among other things) a ZLIB compression, you cannot access the pixel values directly. You need (practically speaking) to decode the image, for example reading it into a BufferedImage with ImageIO.read( )
If for some reason (huge image, memory constraints) you don't like to load the full image in memory in a BufferedImage you could use a progressive reader (eg PNGJ)

What class(es) should I use for basic bitmap operations in GAE?

I have to get some code running on the GAE and it does some very basic bitmap manipulation. What I fundamentally need to do is:
Convert a bitmap from one format to another (usually to PNG).
Get the metadata of an image: size in pixels, DPI, & bitmap format.
Resize an image.
Walk the pixels in a bitmap to read and/or set them (this can be slow - rarely used).
Also, it would be terrific if there's a class that will convert metafiles to a bitmap?
thanks - dave
For basic image manipulation (resize, crop, rotate etc.), you can use the Images API and in particular, the interface com.google.appengine.api.images.Image.
The API seems to support many of the requirements that you mention.

Read/write imag files by lines or by pixels using Java

I have a specific object with image data. And I want read/write images (in BMP, JPEG and PNG formats) to this object.
Of course, I can read/write image into/from BufferedImage and then copy/paste pixels into/from my object. But, I want to do it more faster without intermediate objects!
How can I perform it over standard Java library or throw other Java library?
P.S.:
I know pngj library that allow read PNG images by lines. Maybe you know same libraries for BMP, JPEG (or for all of them: BMP, JPEG, PNG)?
Why don't you just have the BufferedImage in your Object? BufferedImage isn't all that bad. Otherwise, you will need to use something like BufferedImage to convert the image file into pixels, and then read the BufferedImage into something like an int[] array of pixels, but it still requires BufferedImage in the middle, and this would slow things down by adding an extra loop to read over and store the pixels.
Is there a reason why BufferedImage isn't suitable for your purpose?
If you want to do all the reading by yourself, you can just open the file with a stream and read it into an array, but you would need to work your way through the whole structure of the file (headers etc...) if you are working with compressed formats you'd have to work on that too.
Best would be to use imageio to load/write your files and I don't believe there is a lot of overhead coming from the read/write of your images.
Also if you expect to do some heavy work on the images, know that BufferedImages can be hardware accelerated which will improve performance a lot.

How to get image compression quality from IIOMetadata?

When saving a new image with ImageIO generic ImageWriteParam supports explicit setting of compressionQuality parameter from range 0.0f (high compression) to 1.0f (high quality) regardless of image compression algorithm used (eg. png, jpeg, gif).
Is there any way to read compressionQuality from an existing image?
Is that compressionQuality write parameter just a hint to ImageWriter and is not stored anywhere in image's metadata? If that's true how image processing software (e.g. GIMP) manages to provide the following option in 'Save As' dialog?
I managed to read IIOMetadata from ImageInputStream and iterate through its metadataFormatNames to print out image metadata in different XML formats (native and standard javax_imageio_1.0, usually). Although I couldn't find any indication of image's compressionQuality in there.
I don't think that compressionQuality is stored with image meta data, this is processing parameter only.

Categories