JavaXT
|
|||||||||||||||||||||||||
Image IOThe javaxt.io.Image class is designed to simplify reading, writing, and manipulating image files. Here are a couple simple examples of how to open, rotate, crop, resize, and save image files. Please refer to the JavaDocs for a full list of methods. Open an ImageHere's a simple example of how to open an image and print its dimensions:javaxt.io.Image image = new javaxt.io.Image("/photo.jpg"); System.out.println(image.getWidth() + "x" + image.getHeight()); File ConversionHere's a simple example of how to convert a file from one format to another: new javaxt.io.Image("/photo.jpg").saveAs("/photo.png"); Note that the list of supported input and output formats may vary based on the version of your JRE/JDK and whether your application uses JAI. You can get a list of supported input and output formats without instantiating the Image class by accessing static variables. Example: String[] inputFormats = javaxt.io.Image.InputFormats; String[] ouputFormats = javaxt.io.Image.OutputFormats; ResizeThere are several methods to adjust the width/height of an image. javaxt.io.Image image = new javaxt.io.Image("/cup.jpg"); image.setWidth(200); //set width, adjusts height to maintain aspect ratio image.setHeight(50); //set height, adjusts width to maintain aspect ratio image.resize(75, 150); //set width and height to whatever you want
RotateYou can rotate an image with one simple call. You can also flip the image clockwise or counterclockwise. Note that the rotations in this example are additive. javaxt.io.Image image = new javaxt.io.Image("/cup.jpg"); image.rotate(30); image.rotateCounterClockwise(); image.rotateClockwise();
CropYou can crop or subset an image by providing an x,y offset from the upper left corner of the image and a width/height. javaxt.io.Image image = new javaxt.io.Image("/cup.jpg"); image.crop(130,50,80,50);
SkewYou can adjust the corners of the image to arbitrary pixel coordinates. This can be used to add perspective to your images. javaxt.io.Image image = new javaxt.io.Image("/cup.jpg"); int width = image.getWidth(); int height = image.getHeight(); image.setCorners(20, 70, //UL width-70, 0, //UR width+20, height-50, //LR 50, height); //LL
Accessing Raw BytesNote that you can access the raw pixels via the getByteArray() method. byte[] b = image.getByteArray(); By default, this returns a jpeg compressed image. You can specify an output format byte[] b = image.getByteArray("tif"); You can access the raw pixels via the getBufferedImage() method. java.awt.image.BufferedImage bi = image.getBufferedImage(); Image HashYou can use the getPHash() method to generate a perceptual hash value for an image (PHash). Unlike traditional cryptographic hashes like SHA1, PHash is not sensitive to tiny variations in an image. This makes it ideal to find similar (or duplicate) images. You can compare the raw hash values or compute the hamming distance between two hashes to provide a similarity score. In fact, the Image class provides a getHammingDistance() and a isSimilarTo() method to do exactly that! Below is an example of 3 different variations of the same image: (1) the original image, (2) a proportional resize of the original, and (3) distorted resize desaturated copy with a blur filter. All 3 images have the same exact PHash value. Image MetadataIn javaxt-core 1.4.1, we introduced the ability to read image metadata (e.g. EXIF, IPTC, etc.). Here's a simple example of how to parse EXIF metadata created by a digital camera. //Open Image and Get EXIF Metadata javaxt.io.Image image = new javaxt.io.Image("/photo.jpg"); java.util.HashMap<Integer, Object> exif = image.getExifTags(); //Print Camera Info System.out.println("EXIF Fields: " + exif.size()); System.out.println("-----------------------------"); System.out.println("Date: " + exif.get(0x0132)); //0x9003 System.out.println("Camera: " + exif.get(0x0110)); System.out.println("Manufacturer: " + exif.get(0x010F)); System.out.println("Focal Length: " + exif.get(0x920A)); System.out.println("F-Stop: " + exif.get(0x829D)); System.out.println("Exposure Time (1 / Shutter Speed): " + exif.get(0x829A)); System.out.println("ISO Speed Ratings: " + exif.get(0x8827)); System.out.println("Shutter Speed Value (APEX): " + exif.get(0x9201)); System.out.println("Shutter Speed (Exposure Time): " + exif.get(0x9201)); System.out.println("Aperture Value (APEX): " + exif.get(0x9202)); //Print Image Orientation try{ int orientation = (Integer) exif.get(0x0112); String desc = ""; switch (orientation) { case 1: desc = "Top, left side (Horizontal / normal)"; break; case 2: desc = "Top, right side (Mirror horizontal)"; break; case 3: desc = "Bottom, right side (Rotate 180)"; break; case 4: desc = "Bottom, left side (Mirror vertical)"; break; case 5: desc = "Left side, top (Mirror horizontal and rotate 270 CW)"; break; case 6: desc = "Right side, top (Rotate 90 CW)"; break; case 7: desc = "Right side, bottom (Mirror horizontal and rotate 90 CW)"; break; case 8: desc = "Left side, bottom (Rotate 270 CW)"; break; } System.out.println("Orientation: " + orientation + " -- " + desc); } catch(Exception e){ } //Print GPS Information double[] coord = image.getGPSCoordinate(); if (coord!=null){ System.out.println("GPS Coordinate: " + coord[0] + ", " + coord[1]); System.out.println("GPS Datum: " + image.getGPSDatum()); } Here's a simple example of how to parse IPTC metadata. //Open Image and Get IPTC Metadata javaxt.io.Image image = new javaxt.io.Image("/photo.jpg"); java.util.HashMap<Integer, Object> iptc = image.getIptcTags(); //Print Selected Fields System.out.println("IPTC Fields: " + iptc.size()); System.out.println("-----------------------------"); System.out.println("Date: " + iptc.get(0x0237)); System.out.println("Caption: " + iptc.get(0x0278)); System.out.println("Copyright: " + iptc.get(0x0274)); Metadata Resources
Metadata LimitationsThe javaxt.io.Image class relies on the standard ImageIO plugin from Java. Example: ImageReader reader = ... IIOMetadata metadata = reader.getImageMetadata(0); Unfortunately, as of this writing (late 2019), the standard ImageIO plugin relies on some old code from Sun Microsystems which doesn't work correctly for some JPEG images and throws the following exception: javax.imageio.IIOException: JFIF APP0 must be first marker after SOI As a result, some images will appear to have missing metadata. To be clear, the standard JPEG plugin for ImageIO supports both JFIF and Exif JPEGs. However, both these specs require that "their" APP segments being the first segment in the stream. Most readers will be lenient about this, but the standard ImageIO plugin is strict and throws the exception. The good news is that there is a simple workaround using the JPEG ImageIO plugin from TwelveMonkeys. All you need to do is add the following jars to your project and the javaxt.io.Image class will be able to read the metadata without any code changes: common-lang-3.4.2.jar common-io-3.4.2.jar common-image-3.4.2.jar imageio-core-3.4.2.jar imageio-metadata-3.4.2.jar imageio-jpeg-3.4.2.jar imageio-tiff-3.4.2.jar If you do happen to come across an image that doesn't work, please send me an email at email@pborissow.dev |