Package Torello.HTML.Tools.Images
Class ImageInfo
- java.lang.Object
-
- Torello.HTML.Tools.Images.ImageInfo
-
- All Implemented Interfaces:
java.io.Serializable,java.lang.Cloneable
public class ImageInfo extends java.lang.Object implements java.lang.Cloneable, java.io.Serializable
ImageScraper-Suite Class
TheImageScraperTool itself includes three 'Helper-Classes' that facilitate its operations. These three Helpers include:Request,ResultsandImageInfo.
Building a Request:
Building an Image-DownloadRequestinstance really should be extremely easy, and there is an example of doing just that at the top of theRequestclass. Properly configuring the class to handle any / all possible errors or exceptions that might occur when downloading images from a web-server requires a little reading of the JavaDoc pages provided by these tools.
TheRequestclass includes several boolean's for supressing / skipping exception if they occur during the download loop / process iteration. If an exception is thrown and suppressed, it will simply be logged to theResultsclass.
Once aRequestObject has been built, simply pass that object-instance to theImageScrapermethoddownloadand a download-process will begin.Request'sLambda-Targets:
If theRequestobject contained any Lambda-Target / Function-Pointers, then those Lambda-Methods will be passed instances of the 'Helper-Class'ImageInfowhen they are invoked by the download-loop. These Function-Pointers provide just a few features that allow a programmer to do things like filter-out certain Image-URL'sand also do things like decide where a downloaded Image is ultimately stored.
Finally, when the download-loop has run to completely, it will return an instance of classResults
Getting Results:
After theImageScraper.download(...)loop has run to completion, an instance of classResultswill be returned tot he user, and it will simply contain several parallel-arrays that hold / store data about what transpired when trying to download each of the Image-URL'swhich were passed to theRequest-Object.
For instance the 'skipped' array will indicate which pictures didn't download. The 'fileNames' array will hold the name of the file of each image that was successfully downloaded. And the 'imageFormats' will identify which format was ultimately decided-upon when saving the image.
Remember that each of these return-arrays are parallel to eachother, and (or course) will be identical in length. Furthermore, as per the definition of "Parallel-Arrays", the element residing at any index will always correspond to the same image in any one of the other arrays.Simple Image Data-Class that is instantiated by theImageScraper, and passed to any of theFunctionalInterface's or Lambda-Targets that are non-null / available in the user'sRequestobject instance.
In the following example, the programmer is providing a certain method / function to one of theRequestclass' Lambda-Targets. The particular Functional-Interface involved in this example is the one named 'keeperPredicate'.
The'keeperPredicate'allows a user to review everything that is known about a downloaded image before saving it to disk. In this particular example, the Function-Pointer assigned to'keeperPredicate'is one that simple checks whether the most recently downloaded image is a duplicate of the previous one (and if it is, rejects it telling the downloader not to save the image to disk!)
The most important point to understand about the classImageInfois that it is solely used as a "Data-Flow Record" (meaning a small class with lots of data to be passed around) that is transferred to the user whenever the one of the user'sFunctionalInterface'sare invoked by the download-loop!
Example:
private static ImageInfo prevImageInfo = null; // Note that the instance passed to this Function-Pointer / Lambda-Target is an instance of // 'ImageInfo'. All Function-Pointer's in the ImageScraper Request-Object will be passed // an instance of this class. private static boolean keepImage(ImageInfo imageInfo) { if (prevImageInfo == null) { prevImageInfo = imageInfo; return true; } // Simply checks whether two consecutively downloaded images are identical. boolean equal = (imageInfo.width == prevImageInfo.width) && (imageInfo.height == prevImageInfo.height) && (imageInfo.imgByteArr.length == prevImageInfo.imgByteArr.length); prevImageInfo = imageInfo; // Returns 'TRUE' if-and-only-if the previous-image was different than the current image. return !equal; } public static void main(String[] argv) { ... Request req = new Request(images, originalPageURL, true); // Skip-and-move-on for all Image-Download Exceptions req.skipOnAllExceptions(); // Assign the method (defined-above) as the Lambda-Target for the 'keeperPredicate' req.keeperPredicate = MyExampleClass::keepImage; Results r = ImageScraper.download(req, System.out); }
- See Also:
- Serialized Form
Hi-Lited Source-Code:- View Here: Torello/HTML/Tools/Images/ImageInfo.java
- Open New Browser-Tab: Torello/HTML/Tools/Images/ImageInfo.java
File Size: 18,463 Bytes Line Count: 421 '\n' Characters Found
-
-
Field Summary
Serializable ID Modifier and Type Field static longserialVersionUIDImage Source URLModifier and Type Field URLurlBase-64 Encoded Image Fields Modifier and Type Field Stringb64EncodedImageStringimageFormatStrbooleanisB64EncodedImageThe Image Itself, in Two Different Formats Modifier and Type Field java.awt.image.BufferedImagebufferedImagebyte[]imgByteArrImage Specs Modifier and Type Field IFactualExtensionIFguessedExtensionintheightintwidthPlace in the Iterable / List Modifier and Type Field intiteratorCounterintsuccessCounter
-
Method Summary
Lone Getter-Method, for a non-final field Modifier and Type Method StringfileName()Methods: interface java.lang.Cloneable Modifier and Type Method ImageInfoclone()Methods: class java.lang.Object Modifier and Type Method booleanequals(Object other)inthashCode()StringtoString()
-
-
-
Field Detail
-
serialVersionUID
public static final long serialVersionUID
This fulfils the SerialVersion UID requirement for all classes that implement Java'sinterface java.io.Serializable. Using theSerializableImplementation offered by java is very easy, and can make saving program state when debugging a lot easier. It can also be used in place of more complicated systems like "hibernate" to store data as well.- See Also:
- Constant Field Values
-
url
public final java.net.URL url
TheURLthat was used to download the image. Note that anytime this instance ofImageInforepresents an image that was located on a web-page encoded using a Base-64String, then this field will be null, and the B-64 Fields will contain the relevant image data (not thisURL).
-
isB64EncodedImage
public final boolean isB64EncodedImage
If the image whose details are contained by this class-instance are from an image that was encoded using theString-literal Base-64 Encoding Algorithm, then this boolean flag will containTRUE.
An HTML<IMG SRC=...>Tag is the only way to enter a Base-64 Image into the Image-Scraper class.
-
imageFormatStr
public final java.lang.String imageFormatStr
A web-page has the ability to inline (smaller) images directly into an HTML<IMG SRC=...>tag by encoding the picture into a Base-64String. TheStringis saved inside theSRC-Attribute of the<IMG>tag, and contains two separate sub-strings.
This is the first sub-string, and it just identifies / lists the format (.jpg, .gif, .pngetc...) in which the picture was saved before translating it into Base-64 Encoded Text.
If the picture represented by this instance ofImageInfowas downloaded from aURL, then this field will be null, and theurlfield will contain the ImageURL.- See Also:
isB64EncodedImage,b64EncodedImage
-
b64EncodedImage
public final java.lang.String b64EncodedImage
A web-page has the ability to inline (smaller) images directly into an HTML<IMG SRC=...>tag by encoding the picture into a Base-64String. TheStringis saved inside theSRC-Attribute of the<IMG>tag, and contains two separate sub-strings.
This is the second sub-string, and it is the text after translating the picture into Base-64 Encoded Text.
If the picture represented by this instance ofImageInfowas downloaded from aURL, then this field will be null, and theurlfield will contain the ImageURL.- See Also:
isB64EncodedImage,imageFormatStr
-
imgByteArr
public final byte[] imgByteArr
The image, as prepared for saving to disk.
-
bufferedImage
public final java.awt.image.BufferedImage bufferedImage
The image, as an instance ofjava.awt.image.BufferedImage
-
width
public final int width
The value returned bybufferedImage.getWidth()- the downloaded image's width.
-
height
public final int height
The value returned bybufferedImage.getHeight()- the downloaded image's height.
-
guessedExtension
public final IF guessedExtension
This shall help identify whether the image-in-question is aGIF, JPG, PNG, etc.... The field'guessedImageFormat'shall simply contain the image-type based on the extension found in theURL'sfile-name.
There are web-pages & web-sites that do not provide a file-name extension for the images they use on their page(s). In such cases, the downloader will eventually attempt to 'guess' the format of an image that has been downloaded. In these cases, this parameter will be passed null, and the parameteractualImageFormatwill contain the format that was actually used to successfully save the data to disk.
-
actualExtension
public final IF actualExtension
If the image has been properly converted, and is ready to be written to disk, this parameter will contain theIF/ image-format that was used to successfully save the image.
Note that often (but not always), this extension /IFinstance will be identical to the parameter'guessedImageFormat'. There will be cases, as mentioned above, when'guessImageFormat'is null. Furthermore, there may be (very rare) situations when an image-format for a particularURLwas incorrect, and was saved properly using a different format & extension.
-
iteratorCounter
public final int iteratorCounter
Identifies the count in theIterator'sretrieval. Since thisintis used as an array-index pointer, it is initialized to'0'(zero). Specifically, if this method were called upon completion of three iterations of Image-URLretrieval, this counter would contain the integer'2'(two).
-
successCounter
public final int successCounter
This identifies how many images have successfully downloaded, not the number of images for which a "download attempt" occurred. Since thisintis used as an array-index pointer, it is initialized to'0'(zero). If on the third iteration of the source-Iterator, anIOExceptionoccurred between the Java-Virtual-Machine and the internet, the following invocation of this method would havesuccessCounteras'2', but theiteratorCounterwould be'3'.
-
-
Method Detail
-
fileName
public java.lang.String fileName()
A "getter" (Accessor-Method) for theprivate-Field namedfileName. This field is keptprivatebecause it cannot be declaredfinal- since it is initialized several steps after construction.
If a user Lambda-Expression / Functional-Interface has recevied'this'instance ofImageInfo, and needs access to the ultimately-decided-upon image file-name, then this field may be retrieved using this 'Getter' Method.Unitialized at Construction: This method will return null if a user attempts to retrieve the file-name before it has been decided upon and set in this class. This is actually the whole reason that it cannot be declared final, and therefore cannot be declared public (and requires this Getter-Method).- Code:
- Exact Method Body:
return fileName;
-
clone
public ImageInfo clone()
Generates a Shallow Copy of'this'instance. This means that the images themselves are not copied - rather only the references to the images are copied into the clone.
The non-reference, non-instance (primitive-type) fields are all "just copied like normal" :)- Overrides:
clonein classjava.lang.Object- Returns:
- A duplicate instance of this class.
- Code:
- Exact Method Body:
return new ImageInfo(this);
-
toString
public java.lang.String toString()
Converts this class into a simple, readableString- Overrides:
toStringin classjava.lang.Object- Returns:
- A
java.lang.Stringrepresentation of'this'instance. - Code:
- Exact Method Body:
return ((this.url != null) ? ("URL: " + StrPrint.abbrev(this.url.toString(), 40, true, " ... ", 80)) : "") + (this.isB64EncodedImage ? ("B64-Encoded Format: " + this.imageFormatStr + ", IMG: " + StrPrint.abbrev(this.b64EncodedImage, 30, true, " ... ", 60)) : "") + '\n' + "Byte-Array.length: " + StrPrint.commas(this.imgByteArr.length) + '\n' + "W: " + StrPrint.commas(this.width) + ", " + "H: " + StrPrint.commas(this.height) + ", " + "File-Extension: " + Objects.toString(this.actualExtension) + ", " + "URL-Extension: " + Objects.toString(this.guessedExtension) + '\n' + "Iterator-Count: " + this.iteratorCounter + ", " + "Downloaded-Count: " + this.successCounter + '\n' + "Saving File-Name: " + this.fileName + '\n';
-
equals
public boolean equals(java.lang.Object other)
Checks whether'this'instance is equal to'other'.- Overrides:
equalsin classjava.lang.Object- Parameters:
other- Any Java Object, but only an instanceImageInfo(or a class that is assignable to it) could possible generate aTRUE-return value.- Returns:
TRUEIf and only if'other'is an instance ofImageInfo, and if the contents of that are instance are identical to the contents of'this'instance.- Code:
- Exact Method Body:
if (other == null) return false; if (! ImageInfo.class.isAssignableFrom(other.getClass())) return false; ImageInfo ii = (ImageInfo) other; // Note that using 'Objects.equals(...)' and 'Objects.deepEquals(...)' primarily prevents // a NullPointerException from being thrown if the left side of an '.equals(...)' were to // be null. It's really nothing more than that. (A small 'Convenience' that makes this // method look less ridiculous than it already does.) // // 'deepEquals(...)' actually checks the entire contents of two array's for equality. return // Image-URL (very common) Objects.equals(this.url, ii.url) // Base-64 Image Stuff (rare, but not impossible) && (this.isB64EncodedImage == ii.isB64EncodedImage) && (Objects.equals(this.imageFormatStr, ii.imageFormatStr)) && (Objects.equals(this.b64EncodedImage, ii.b64EncodedImage)) // The actual downloaded and converted images, themselves && Objects.deepEquals(this.imgByteArr, ii.imgByteArr) && Objects.equals(this.bufferedImage, ii.bufferedImage) // Image-Width, Image-Height && (this.width == ii.width) && (this.height == ii.height) // URL-Aquired Extension & Ultimately-Decided-Upon Extension && Objects.equals(this.guessedExtension, ii.guessedExtension) && Objects.equals(this.actualExtension, ii.actualExtension) // class 'Results' Array-Counters (index-pointers) && (this.iteratorCounter == ii.iteratorCounter) && (this.successCounter == ii.successCounter) // This is the lone / only 'non-final' field && Objects.equals(this.fileName, ii.fileName);
-
hashCode
public int hashCode()
Java's hash-code requirement. The code is computed by summing the first 15imgByteArrarray elements.- Overrides:
hashCodein classjava.lang.Object- Returns:
- A hash-code that may be used when storing this node in a java sorted-collection.
- Code:
- Exact Method Body:
if (url != null) return url.toString().hashCode(); int sum = 0; for (int i=0; (i < 15) && (i < imgByteArr.length); i++) sum += imgByteArr[i]; return sum;
-
-