SkillAgentSearch skills...

Imgscalr

Simple Java image-scaling library implementing Chris Campbell's incremental scaling algorithm as well as Java2D's "best-practices" image-scaling techniques.

Install / Use

/learn @rkalla/Imgscalr
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

imgscalr - Java Image-Scaling Library

Changelog

4.2 * Added support for a new Method.ULTRA_QUALITY scaling method.

This new method uses 3.5x more incremental steps when scaling an image down
than the QUALITY method, providing a much more accurate result. This is
especially noticeable in thumbnails that have diagonal lines that get jagged
during down-sizing with QUALITY or lower methods.

The quality of the ULTRA_QUALITY scaling method is almost on par with the
image resize functionality built into Mac OS X; that is to say it is better
than GIMP's Lancsoz3 and Windows 7 built-in resize.

https://github.com/rkalla/imgscalr/issues/61

* Fixed subtle bug with incremental scaling and Mode.FIT_EXACT causing the
incremental scaling to stop too soon resulting in the wrong-sized result
image.

The stop-condition for incremental scaling assumed that in every case the
width AND height would be shrinking each iteration; when using 
Mode.FIT_EXACT this is not necessarily true as one dimension may not change
at all or stop changing before another.

https://github.com/rkalla/imgscalr/issues/65 

4.1 * Fixed NullPointerException that occurred when debugging was enabled https://github.com/rkalla/imgscalr/issues/60

Required a patch-release due to the show-stopping nature of the bug.

4.0 * [BREAKING] Package has changed from com.thebuzzmedia.imgscalr to org.imgscalr - I am sorry for the inconvenience of this, but this is necessary. There will be a family of imgscalr-based Java utilities coming out in the future (ExifTool is next) that will all be under this umbrella.

* [BREAKING] Java 6 is now required for using imgscalr. 

The reason for this is because imgscalr includes specific types of 
ResizeOp and ColorConvertOps that actually segfault the latest Java 5 VM 
when applied, but run fine in Java 6 and 7.

imgscalr cannot knowingly ship VM-segfaulting code that could would 
introduce a potentially	devastating situation into client applications.

This decision was not made lightly, but with Java 5 end-of-lifed and Java 6
being out for 5 years, it seemed like a reasonable requirement.

* [BREAKING] Rotation enum was totally redefined. All rotations were 
redefined in terms of 90,180,270 quadrant rotations as well as h/v FLIP.

* [BREAKING] All resize(...) methods that accepted Rotation enums are 
removed. All graphic operations are now separate and discrete, but can be
easily combined when multiple effects are wanted.

* Added apply() support for applying an arbitrary list of BufferedImageOps
SAFELY and efficiently working around all the bugs in the JDK pertaining
to BufferedImageOps (also used internally when applying any optionally 
specified ops).

* Added crop() support.

* Added pad() support.

* Added rotate() support.

* All graphic operations (even new ones) were modified to allow the 
application of 1 or more BufferedImageOps to a final image result before
returning it for convenience.

* Support for all the new operations (apply, crop, pad, rotate) were all 
added to AsyncScalr so these operations can all be asynchronously performed 
as well.

* Added support for horizontal and vertical flipping of the image via the
Rotation enum and new rotate() method.

* Added pre-defined OP_DARKER and OP_BRIGHTER operations that can be applied
to any image to make them darker or brighter (respectively) by 10%.

* Added Mode.FIT_EXACT to support (for the first time) scaling images 
forced into a specific given dimension instead of honoring the image's
orientation and proportions automatically. 

* AsyncScalr's use of ExecutorService was rewritten; no more support for
passing in custom ExecutorService implementations or modifying existing ones
on the fly and having the class do something magic to them under the
covers (that was bad) -- just extend the class and specify your own logic.

* AsyncScalr can be easily customized now through a single method:

	- createService()
	  OR
	- createService(ThreadFactory)
	
* AsyncScalr provides two custom ThreadFactory implementations for subclasses
to use if they want to customize the types of Threads generated and used 
internally for async scale operations.

	- DefaultThreadFactory creates default threads with all default settings.
	- ServerThreadFactory generates threads that are optimized to execute in
	  a server environment (daemon threads w/ LOW_PRIORITY).

* AsyncScalr.DEFAULT_THREAD_COUNT was removed and replaced with THREAD_COUNT
that can be customized and set via system properties.

* AsyncScalr.THREAD_COUNT's property name was separated into a String constant
to make it easier to work with.

* Simplified the resize() calls as a result of making all operations discrete;
8 duplicate methods accepting "rotation" arguments were removed.

* Optimized the application of BufferedImageOps.

* Fixed a bug in the application of BufferedImageOps which could have led
to an ImagingOpException bubbling up from native Java2D or a corrupt (black)
image for poorly supported image types.

* Memory optimized the application of 2 or more BufferedImageOps (interim
images are explicitly cleaned up just like in incremental scaling).

* Optimized log() implementation to avoid StringBuilder creation and string
concatenation. Should be significant run-time savings over time if you are
running in an environment with debugging turned on.

* Removed the identity-return functionality in each method to throw an 
exception instead of silently returning "src" unchanged.

This was done intentionally to avoid users getting caught in the situation
where they have code that automatically calls flush() on "src" after an
imgscalr method has returned (assuming they NOW have a modified copy to work
with). 

In the case of sending in invalid or null arguments, previously imgscalr
would return "src" unchanged, which means the caller would be calling
flush() on a perfectly good image they still needed and not a copy as was
assumed by using imgscalr (And there would be no way to tell if imgscalr had
created a copy or not without using an == check with EVERY returned image
result).

Instead, invalid or missing arguments passed to any imgscalr method are
now considered an exception so the caller knows IMMEDIATELY when something
is wrong and won't get magically different/unexpected behavior.

* Exposed the potential for every method to fire an ImagingOpException if
one of the BufferedImageOps fails to apply using the hardware-accelerated
underlying Java2D code path. These exceptions were previously hidden in the
guts of Java2D and could bubble up unexpectedly, now they are clearly defined
directly on the imgscalr API so they can be cause and handled IF the caller
wants or needs to do that when using custom BufferedImageOps.

* Detailed notations about performance optimizations the caller can make to
ensure their handling of images are as performant as possible were added to
all the methods as a convenience.

* Defined DEBUG system property name as a public constant that can be used
to help avoid misspellings when trying to set debugging on.

* Modified LOG_PREFIX so it can now be set via the "imgscalr.logPrefix" 
system property value now.

* Rewrote imgscalr test suite to specifically test all discrete operations
and all variations of the operations as well.

* Added AllTests test suite so all tests can be easily run at one time to
verify the release.

* Rewrote Javadoc covering a lot of the return and exception conditions for
all the methods to more clearly communicate what is happening inside the
method and to the original images.

3.2 * Added support for asynchronous & rate-limited scaling operations via the AsyncScalr class.

The AsyncScalr class wraps the parent Scalr class and submits scale jobs to
an internal ExecutorService. The executor service can be used to serialize
and queue up scaling operations to avoid blowing the heap and overloading the
underlying host on a busy, multi-user system (e.g. a web app running imgscalr).

AsyncScalr by default uses a fixed-size ThreadPoolExecutor that can be modified
at run time to any tuned level of threads the caller desires (default 2). The
default settings are intended to be safe/efficient to use out of the box on 
most all systems.

Additionally, AsyncScalr can be configured to use *any* ExecutorService 
implementation passed to it so callers have ultimate control over how the 
AsyncScalr processes jobs if they need/want it.

Typically it is a good idea to roughly map # of Scaling Threads to the # of 
Cores on the server, especially on a server with plenty of memory and a large
heap for the VM.

If you are running inside of a smaller VM heap or lower-memory server (regardless
of core count) you will want to limit the number of simultaneous scale operations
so as not to saturate the heap during scaling when the images are read into
internal BufferedImage instances in VM memory.

* Added support for Rotation to the library. You can now specify the following
rotations to be applied to your image:

Rotation.NONE - No rotation.
Rotation.CLOCKWISE - Clockwise (90 degrees to the right) rotation.
Rotation.COUNTER_CLOCKWISE - Counter-clockwise (90 degrees to the left) rotation.
Rotation.FLIP - Flip the image (180 degrees rotation).

The rotation is performed as tightly and efficiently as possible, explicitly
cleaning up temporary resources created during the operation.

* API was simplified as duplicate methods without the vararg parameter were
removed (these were effectively duplicates of the vararg methods make the
API longer than it needed to be).

* Corrected a multitude of incorrect Javadoc comments pertaining to @throws
conditions.

* Rewrote the method Javadoc. Manually reviewing uncovered too many copy-paste
discrepancies that left out important information

Related Skills

View on GitHub
GitHub Stars1.2k
CategoryDevelopment
Updated3d ago
Forks235

Languages

Java

Security Score

95/100

Audited on Apr 1, 2026

No findings