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
TheImageScraper
Tool itself includes three 'Helper-Classes' that facilitate its operations. These three Helpers include:Request
,Results
andImageInfo
.
Building a Request:
Building an Image-DownloadRequest
instance really should be extremely easy, and there is an example of doing just that at the top of theRequest
class. 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.
TheRequest
class 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 theResults
class.
Once aRequest
Object has been built, simply pass that object-instance to theImageScraper
methoddownload
and a download-process will begin.Request's
Lambda-Targets:
If theRequest
object contained any Lambda-Target / Function-Pointers, then those Lambda-Methods will be passed instances of the 'Helper-Class'ImageInfo
when 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's
and 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 classResults
will 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's
which 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'sRequest
object instance.
In the following example, the programmer is providing a certain method / function to one of theRequest
class' 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 classImageInfo
is 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's
are 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,445 Bytes Line Count: 420 '\n' Characters Found
-
-
Field Summary
Serializable ID Modifier and Type Field static long
serialVersionUID
Image Source URL
Modifier and Type Field URL
url
Base-64 Encoded Image Fields Modifier and Type Field String
b64EncodedImage
String
imageFormatStr
boolean
isB64EncodedImage
The Image Itself, in Two Different Formats Modifier and Type Field java.awt.image.BufferedImage
bufferedImage
byte[]
imgByteArr
Image Specs Modifier and Type Field IF
actualExtension
IF
guessedExtension
int
height
int
width
Place in the Iterable / List Modifier and Type Field int
iteratorCounter
int
successCounter
-
Method Summary
Lone Getter-Method, for a non-final field Modifier and Type Method String
fileName()
Methods: interface java.lang.Cloneable Modifier and Type Method ImageInfo
clone()
Methods: class java.lang.Object Modifier and Type Method boolean
equals(Object other)
int
hashCode()
String
toString()
-
-
-
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 theSerializable
Implementation 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
- Code:
- Exact Field Declaration Expression:
public static final long serialVersionUID = 1;
-
url
public final java.net.URL url
TheURL
that was used to download the image. Note that anytime this instance ofImageInfo
represents 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
. TheString
is 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, .png
etc...) in which the picture was saved before translating it into Base-64 Encoded Text.
If the picture represented by this instance ofImageInfo
was downloaded from aURL
, then this field will be null, and theurl
field will contain the ImageURL
.- See Also:
isB64EncodedImage
,b64EncodedImage
- Code:
- Exact Field Declaration Expression:
public final String imageFormatStr;
-
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
. TheString
is 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 ofImageInfo
was downloaded from aURL
, then this field will be null, and theurl
field will contain the ImageURL
.- See Also:
isB64EncodedImage
,imageFormatStr
- Code:
- Exact Field Declaration Expression:
public final String b64EncodedImage;
-
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's
file-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 parameteractualImageFormat
will 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 /IF
instance 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 particularURL
was incorrect, and was saved properly using a different format & extension.
-
iteratorCounter
public final int iteratorCounter
Identifies the count in theIterator's
retrieval. Since thisint
is 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-URL
retrieval, 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 thisint
is used as an array-index pointer, it is initialized to'0'
(zero). If on the third iteration of the source-Iterator
, anIOException
occurred between the Java-Virtual-Machine and the internet, the following invocation of this method would havesuccessCounter
as'2'
, but theiteratorCounter
would be'3'
.
-
-
Method Detail
-
fileName
public java.lang.String fileName()
A "getter" (Accessor-Method) for theprivate
-Field namedfileName
. This field is keptprivate
because 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:
Note that 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).
-
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:
clone
in 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:
toString
in classjava.lang.Object
- Returns:
- A
java.lang.String
representation 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: " + StringParse.commas(this.imgByteArr.length) + '\n' + "W: " + StringParse.commas(this.width) + ", " + "H: " + StringParse.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:
equals
in 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:
TRUE
If 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 15imgByteArr
array elements.- Overrides:
hashCode
in 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;
-
-