-
Notifications
You must be signed in to change notification settings - Fork 793
Changes
This release addresses the following issue:
- Issue 207 - Fixed issue with incorrect source region being selected for JPEG images with certain Exif orientation.
This release addresses the following issue:
- Issue 202 - Defined an automatic module name in the manifest. This allows Thumbnailator to have a module name that doesn't rely on the JAR file name under the Java Platform Module System.
This release addresses the following issue:
- Issue 91 - Fixed issue where JPEG images with certain Exif orientations would have incorrect dimensions.
This release fixes a performance issue introduced in 0.4.16.
Unnecessary calls to Arrays.toString
in debug logging calls were removed.
The performance impact from the problem in 0.4.16 was negligible (less than 0.5%) in simulated workloads. Therefore, the impact of this fix is reducing unnecessary object allocation.
This release addresses the following issue:
-
Issue 108 - Added workaround to properly orient thumbnails for JPEGs where Exif is the first non-SOI marker segment when using the default JPEG reader. The default JPEG reader included in Java cannot retrieve Exif from JPEGs where APP1 marker segment (like Exif) comes before the APP0 marker segment.
This workaround can be disabled by setting the system property
thumbnailator.disableExifWorkaround
totrue
.
This release addresses the following issues:
-
Issue 156 - Fixed issue with PNG file sizes being larger in Java 9 or later. Java 9 has changed the behavior the default PNG image writer to use a lower compression level. A workaround has been added to keep the same compression level as Java 8 and prior.
-
Issue 175 - Fixed issue with Javadocs failing to build in Java 8 or later.
-
Issue 162 - Added ability to configure insets of the watermark. This is convenient when offsetting the watermark from the corner of the thumbnail.
Insets can be specified through the
.watermark(Position, BufferedImage, float, int)
method:// Position watermark so that the bottom-right corner is five pixels away // from the bottom-right corner of the thumbnail. Thumbnails.of("path/to/image") .size(100, 100) .watermark(Positions.BOTTOM_RIGHT, watermarkImage, 0.5f, 5) .toFile("path/to/thumbnail");
- Fixed a potential resource leak (unclosed output stream) when an I/O error occurs while writing a thumbnail to a file.
Issue was in the
FileImageSink
class, pointed out in this comment.
This release addresses the following issues:
-
Issue 157 - Fixed a bug that caused unexpected
BufferedImage
image types. A few image filters (e.g. used through the.rotate
and Exif-based rotations) were corrected.This fix may introduce unexpected behavior changes in existing code. While regression tests did not detect any issues, some caution is advised when switching to this version.
The original issue was caused by certain image filters changing the
BufferedImage
image type toBufferedImage.TYPE_INT_ARGB
. If an issue is encountered, using.imageType(BufferedImage.TYPE_INT_ARGB)
may restore the behavior prior to this version. -
Issue 161 - Fixed a division-by-zero bug when engaging memory conservation mode with
thumbnailator.conserveMemoryWorkaround
.
This release addresses the following issues:
-
Issue 143 -
Fixed a resource leak (an unclosed
InputStream
) when an exception occurs while opening source files and streams.
- Updated unit tests to work properly under OpenJDK.
- Removed generated Javadocs from the source tree.
- Reformatted code to use Unix-style line ending (line feed only), and changed brace style.
This release addresses the following issues:
-
Issue 149 -
Fixed a resource leak (an unclosed
FileInputStream
) when opening source files.
This release addresses the following issues:
-
Issue 148 -
Fixed a resource leak (an unclosed
FileOutputStream
) when writing thumbnails to files.
This release addresses the following issues:
-
Issue 107 - Fixed problem with Java2D rendering hints not being applied to progressive bilinear resizing, when image could be resized in one step.
-
Issue 118 - Fixed incorrect IFD Type for
SRATIONAL
in the Exif reader. -
Fixed bug where unused output files were being created.
Files which were going to be rejected at the output step (due to being a file format that isn't supported) were being created before the output step. This left behind files which should have not been created.
This release is a very minor update which includes a workaround to attempt to reduce the likeliness of OutOfMemoryError
s from occurring. (Refer to the "OutOfMemoryError
Workaround" section for details.)
In addition, the build tooling for Thumbnailator has been changed from Ant to Maven. (Issue 68) This has necessitated major re-arrangement of source files to conform with the Maven project layout.
Other minor changes include updating an out-of-date comment about implementation in the Thumbnailator
class (Issue 68) and added line number information to the Thumbnailator JAR file to assist in debugging. (Issue 71)
Thumbnailator 0.4.8 is available via Maven, and JAR files can be downloaded from The Central Repository.
Issues around OutOfMemoryError
s have been recognized from the early stages of development of Thumbnailator. (Issue 1)
However, to fundamentally address the issue requires some dramatic design changes to the core parts of Thumbnailator which would take some time and would affect many internal parts of the library. Such changes would take time before being implemented, a temporary workaround has been added to Thumbnailator 0.4.8 to reduce the likeliness of OutOfMemoryError
s. (Issue 69)
The workaround is not enabled by default, as it can negatively affect the quality of the final image, and has not been extensively tested, and will not necessarily avoid OutOfMemoryError
s.
The workaround can be enabled by one of the following ways:
- Starting the JVM with an argument
-Dthumbnailator.conserveMemoryWorkaround=true
, or - By setting a system property key
thumbnailator.conserveMemoryWorkaround
with the valuetrue
.
With the workaround enabled, a smaller version of the source image will be used to reduce memory usage, under the following conditions:
- Both height and width have dimensions larger than 1800 pixels
- The expected memory size of the source image will take up more than 1/4 of the available JVM free memory
This workaround should not be considered a part of the Thumbnailator's public API. This workaround will be removed when its no longer considered useful by the author, therefore, code invoking Thumbnailator should not depend upon this workaround being always present.
This release added an user-requested feature (Issue 51) to change the output directory of the thumbnails when using the toFiles(Rename)
or asFiles(Rename)
method.
The following methods have been added:
This release addresses the following issues:
-
Issue 54 - Fixed problems where
ant
could not be used to build Thumbnailator.- Originally,
build.xml
depended on files created by Eclipse, but the dependency has been removed - Some unit test cases would only pass on Java 5, but conditional checks has been added so that it will pass on Java 5 and up. (This has been verified for Java 5, 6 and 7.)
- Originally,
-
Issue 55 - Fixed a bug that caused the watermark to disappear in certain circumstances when using crop.
-
Issue 56 - Fixed a bug which caused the watermark to be incorrectly positioned when the EXIF orientation metadata was used to re-orient the image.
A change has been made to the location of the LICENSE
file.
Originally, the LICENSE
file was located in the resources
directory, but it has been moved to the root.
In addition, the LICENSE
file has been added to the META-INF
directory of the JAR files being distributes via the downloads and via the Maven Central repository.
This release addresses an issue where the Exif orientation metadata was not being used in the Thumbnailator.createThumbnail
methods. (Issue 43)
This release fixes a bug which causes OutOfMemoryError
s when running Thumbnailator on the latest versions of Java 6 and 7 -- Java 6 Update 45 and Java 7 Update 21. (Issue 42)
Many thanks goes out to Vladimir Shomin, Will Tran and others for providing valuable information in tackling this problem.
This release adds support for using the Exif metadata to properly orient thumbnails. (Issue 13, Issue 27)
Now, the default behavior is to use the Exif metadata to determine the correct orientation of the thumbnail.
However, this behavior can be overridden by disabling the usage of theExif metadata by calling the
useExifOrientation
method with
false
as the argument.
In addition, the message included in the IOException
thrown when an error occurs while processing has been changed to better indicate what had occurred. (Issue 27)
This release fixes an issue where the thumbnails are given incorrect file names when using the Rename.SUFFIX_DOT_THUMBNAIL
or Rename.SUFFIX_HYPHEN_THUMBNAIL
rename option,
if the original file name contains multiple "." characters.
(See Issue 36 for details.)
This release changes the behavior of deciding the size of the thumbnail.
Up to Thumbnailator 0.4.0, the code used to determine the size of the thumbnail was rounding down (in other words, truncating) the dimensions.
For example, if the new dimension was calculated to be 15.4
or 15.6
, the resulting dimension would both be 15
.
Also, there were instances where the dimension(s) of the thumbnail could become 0, leading to an IllegalArgumentException
being thrown
when attempting to make a thumbnail.
From Thumbnailator 0.4.1, the code has been revised to round to the closest integer by using the Math.round
method.
This means that if the new dimension was calculated to be 15.4
the resulting dimension would both be 15
, while a new dimension of 15.6
would result in the dimension being 16
.
Also, the minimum size of a thumbnail's dimension has been specified to be one. Therefore, under conditions which could lead to the thumbnail
having a dimension of zero, the dimension will be promoted to 1
, therefore, the aspect ratio of a thumbnail may not be necesarily maintained.
The following summarizes the changes in thumbnail size between previous versions of Thumbnailator and the current version when using the builder interface*
:
From a original image with dimensions 100 x 106:
version | size after .size(10, 10) |
size after .scale(0.1) |
---|---|---|
before 0.4.1 | 10 x 10 | 10 x 10 |
0.4.1 | 10 x 11 | 10 x 11 |
From a original image with dimensions 100 x 104:
version | size after .size(10, 10) |
size after .scale(0.1) |
---|---|---|
before 0.4.1 | 10 x 10 | 10 x 10 |
0.4.1 | 10 x 10 | 10 x 10 |
From a original image with dimensions 100 x 6:
version | size after .size(10, 10) |
size after .scale(0.1) |
---|---|---|
before 0.4.1 | IllegalArgumentException |
IllegalArgumentException |
0.4.1 | 10 x 1 | 10 x 1 |
*
The builder interface refers to the use of the Thumbnails
class as the entry point when making thumbnails, such as in the code below:
Thumbnails.of("path/to/image")
.size(10, 10)
.toFile("path/to/thumbnail");
The specification of the following classes have been changed in order to implement the changes of calculating the size of the thumbnails:
-
FixedSizeThumbnailMaker
class -
ScaledThumbnailMaker
class
This release introduces new functionality and minor changes to the API. Please note that upgrading to the Thumbnailator 0.4.0 may require changing to existing code.
-
Introduction of the
ResizerFactory
interface which allows finer control over the resizing of images.- Enables the use of alternate resizing algorithms.
- Enables differing resizing strategies depending on the dimensions of the source and destination images.
- Internal resizing routines have been reworked to use
ResizerFactory
's.
-
The
ResizerFactory
class in the 0.3.x series has been essentially renamed to theDefaultResizerFactory
class. -
The following deprecated methods have been removed:
fromFilenames(Collection<String>)
fromFiles(Collection<File>)
fromURLs(Collection<URL>)
fromInputStreams(Collection<InputStream>)
fromImages(Collection<BufferedImage>)
Although the from...(Collection)
method have been removed, the from...(Iterable)
methods should be functionally equivalent for most scenarios.
For example, using a List
as the argument of the from...
methods will work the same as before.
The below code will work under Thumbnailator 0.3.x and 0.4.x without any modifications:
List<String> filenames = new ArrayList<String>();
filenames.add("path/to/image1.jpg");
filenames.add("path/to/image2.jpg");
Thumbnails.of(filenames)
.size(200, 200)
.toFiles(Rename.PREFIX_DOT_THUMBNAIL);
-
The
Rename
class now accepts an additionalThumbnailParameter
as its argument, which enables finer control over determining a name for the resulting thumbnail image file by providing more context about the image resizing operation. -
Added the
crop(Position)
method to crop the thumbnail after it has been resized while keeping the aspect ratio. This method has been added to address Issue 24.
For example, resizing the image from 240x200 to 100x100 using the crop
method would result in the following:
- Fixed two bugs in the
Canvas
class.- The background color of images with transparency was being filled black when it should have been left transparent.
- The width and height of the Canvas could potentially be altered when the
Canvas.apply
method is called multiple times.
Added the scale(double, double)
method to create thumbnails by specifying the scaling factors for the width and height independently. This feature implements the feature request in Issue 19.
- Fixed an issue where the file extensions assigned to thumbnails would violate the principle of least surprise. (See Issue 18 for details.)
- Fixed an issue where the file that the thumbnail was written to remains open, preventing certain programs from accessing the file. (See Issue 17 for details.)
Added the allowOverwrite(boolean)
to specify the behavior of whether or not to overwrite existing files when creating thumbnails.
The allowOverwrite(boolean)
method will affect the behavior of the following methods:
toFile(File)
toFile(String)
toFiles(Iterable<File>)
toFiles(Rename)
asFiles(Iterable<File>)
asFiles(Rename)
Some changes have been made to the behavior of the methods listed above with respect to handling files which have not been written due to the destination file existing at the time the thumbnails were being produced.
- Fixed an issue which was causing thumbnails to be incorrectly written to the destination file if it already exists. (See Issue 14 for details.)
A feature has been added to create a thumbnail by only specifying either the width or height, as requested in Issue 12.
The feature will use the specified width or height (via the width
and height
methods) as the constraint, and create a thumbnail which preserved the aspect ratio of the original image.
For example, resizing a 400x300 image with the width constraint specified to 200, the thumbnail will be 200x150.
The code to perform the resize will be as follows:
Thumbnails.of("/path/to/image-400x300")
.width(200)
.toFile("/path/to/thumbnail-200x150")
The following methods were added to the Thumbnails
fluent interface:
It is now possible to specify the source region from which a thumbnail is produced, as requested in Issue 6.
For example, creating a 200x200 thumbnail from the center 400x400 region of the source image could be written like the following:
Thumbnails.of("/path/to/image")
.sourceRegion(Positions.CENTER, 400, 400)
.size(200, 200)
.toFile("/path/to/thumbnail")
The following methods were added to the Thumbnails
fluent interface:
sourceRegion(Region)
sourceRegion(Position, Size)
sourceRegion(int, int, int, int)
sourceRegion(Position, int, int)
sourceRegion(Rectangle)
In order to implement the source region selection feature, new interfaces and classes were added to the net.coobird.thumbnailator.geometry
package, and
some retrofitting were done to classes such as ThumbnailParameter
and the ImageSource
subclasses.
The additions to Thumbnailator are backward compatible, and should not affect code written against the Thumbnailator 0.3.x API.
- Fixed a bug which causes an
IllegalStateException
when creating a GIF thumbnail with the compression quality settings specified. (See Issue 9 for details.)
- Added the
forceSize
method to theThumbnails
builder interface to force the size of the thumbnail to the specified dimensions. (equivalent to using thesize
method along with thekeepAspectRatio(false)
method.) - Added the
Canvas
image filter class which can be used to crop or add a border to the resulting thumbnail.
- It is now possible to use an
Iterable
to specify the original images through one of thefrom
methods:fromFilenames(Iterable<String>)
fromFiles(Iterable<File>)
fromURLs(Iterable<URL>)
fromInputStreams(Iterable<? extends InputStream>)
fromImages(Iterable<BufferedImage>)
- Previous
from
methods which acceptCollection
s have been deprecated.
This release introduces significant new functionality and changes to the API. Please note that upgrading to the Thumbnailator 0.3.0 may require changing to existing code. (In most use cases, changes will be limited to updating import
statements and adding exception handling. See below for details.)
- Enhanced support for inputs and outputs
- Removed the restriction that the output type must be the same as the input type -- for example, Thumbnailator 0.2.x required that a thumbnail created from an image file be saved to a file.
- It is now possible to retrieve thumbnails as an
Iterable
- This feature allows retrieval of thumbnails as they finish processing, rather than waiting until all thumbnails are processed.
- This can potentially avoid
OutOfMemoryError
s, as Thumbnailator only needs to hold a reference to one thumbnail at a time. - Added input sources and output destinations.
- Added support for retrieving images from
URL
s andInputStream
s. - Added support for storing thumbnails to
OutputStream
s.
- Added support for retrieving images from
- Added APIs to generate file names.
- Newly created
net.coobird.thumbnailator.name
package contains classes to generate file names for thumbnails being saved to files.
- Newly created
The following are backward incompatibles changes:
- Reorganized packages.
- Moved
Coordinate
,Position
andPositions
classes to thenet.coobird.thumbnailator.geometry
package. - Moved the
Rename
class to thenet.coobird.thumbnailator.name
package. - Moved the
BufferedImages
andThumbnailatorUtils
classes to thenet.coobird.thumbnailator.util
package.
- Moved
- Removed deprecated methods and classes.
- Methods and classes which were marked as deprecated in Thumbnailator 0.2.x have been removed.
- All output methods of the fluent interface (including
asBufferedImages
andasBufferedImage
) now throwIOException
- Added the
Transparency
image filter for changing the opacity of the resulting thumbnail. - Fixed a bug where calling the
asBufferedImage
method causes aNullPointerException
if the original images did not originate from aBufferedImage
.
- Minor changes were made to the
Thumbnails
builder interface.- Added an override for the
outputQuality
method which accepts adouble
. - Added null argument checks for in the configuration methods of the builder interface.
- Added an override for the
- Checks were added to
scalingMode(ScalingMode)
,resizer(Resizer)
,alphaInterpolation(AlphaInterpolation)
,dithering(Dithering)
,antialiasing(Antialiasing)
, andrendering(Rendering)
. * Added checks to see that a supported format is specified in theoutputFormat
method.
* Added checks to theoutputFormatType
method, to ensure that the type and format parameters will not be in a state which could cause problems when saving thumbnails.
- Added methods to the
Thumbnails
builder interface to acceptCollection
s. - Fixed the behavior for adding a file extension to the name of the resulting thumbnail when the output format does not match the given extension.
- Updated the
ThumbnailParamterBuilder
class to better support the current specification of theThumbnailParameter
class.
- Fixed an issue where saving a thumbnail with transparency to a BMP image causing an exception.
- Changed
ThumbnailTask.write
from returningboolean
tovoid
, and added theUnsupportedFormatException
class used to indicate that a format is not supported for the specified operation.- The
StreamThumbnailTask
andFileThumbnailTask
classes have had theirwrite
methods modified to throw theUnsupportedFormatException
and not return aboolean
on return.
- The
- Added
Thumbnailator.createThumbnail(InputStream, OutputStream, String, int, int)
which can be used to specify the format to use for the output data. - Changed the
asBufferedImage
method to throw anIllegalArgumentException
when multiple images are specified in theBuilder.of
method. This makes the behavior more consistent with thetoFile
method. - Removed the restriction that
Thumbnails.Builder.asBufferedImage
must haveBufferedImage
s as the source. -
ThumbnailMaker
classes will now throw anIllegalStateException
when the size, aspect ratio or scaling factor is specified more than once.- The
FixedSizeThumbnailMaker
andScaledThumbnailMaker
classes have been modified due to this change.
- The
- Added null argument checks for the
Thumbnails.of
methods.
- Changed the
Thumbnails
class to create thumbnails with the same image type as the original image.- This change was made to address an issue where color distortions occurred in the resulting thumbnail when the original image was a JPEG. This occurred due to the original behavior to create a thumbnail image with an alpha channel. The default JPEG encoder implementation which ships with the JRE appears to cause color distortions for images which contain an alpha channel.
- Changed the
FileThumbnailTask.read()
method to throw aFileNotFoundException
when theFile
specified to obtain the original image does not exist. - Added and improved documentation.
- Fixed issues with the
ProgressiveBilinearResizer
class.- Fixed an issue which lead to quality degradations for thumbnails when the original image was less than twice the size of the thumbnail.
- Fixed an issue with thumbnails of transparent images containing magnified images of the thumbnail in the background.
- The
Thumbnails
class is now the entry-point into the fluent interface of Thumbnailator.- The non-fluent interface methods have been moved from the
Thumbnails
class to theThumbnailator
class. - The non-fluent methods such as
createThumbnails
remain in theThumbnails
class, however, they have been deprecated and will be removed in the next major revision of Thumbnailator.
- The non-fluent interface methods have been moved from the
- The
Thumbnails.Rename
has been promoted to a top-level class.- The class remains available in the
Thumbnails
class, however, it has been deprecated and will be removed in the next major revision of Thumbnailator.
- The class remains available in the
- Added the
Thumbnails.resizer
to specify theResizer
to use when creating thumbnails.
- Added new builder interface to
Thumbnails
class. - Many changes to support the new builder interface.
- Added documentation and fixed bugs.
- Changed the resizing routine to improve image quality.
- Fixed issue with trying to set compression parameters for codecs which don't support compression.
- Added checks for allowed values for method arguments in many locations.
- Changed the signature of
Thumbnails.createThumbnailCollection
method. - Fixed issue with color distortion in JPEG images by adding a workaround when writing to JPEGs.
- Initial release.