Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Next

* Add a JRuby-only Java2D/ImageIO processor available as `ImageProcessing::Java2D`

## 2.0.3 (2026-06-08)

* Prevent remote code execution when operation names come from user input, closing bypasses through the `#operation` meta-builder, `#method_missing`, and nested `#send` calls (reported by @szymonsec)
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This gem can process images with [ImageMagick] or [libvips]. ImageMagick is a
good default choice, especially if you are migrating from another gem or library
that uses ImageMagick. Libvips is a newer library that can process images [very
rapidly][libvips performance] (often multiple times faster than ImageMagick).
On JRuby, it can also process images with the Java2D image APIs.


## Goal
Expand Down Expand Up @@ -50,9 +51,16 @@ In a Mac terminal:
gem "ruby-vips", "~> 2.0" # if using libvips
```

On JRuby, `ImageProcessing::Java2D` uses only the bundled Java2D image APIs, so
it needs no additional gem or native library. MiniMagick and Vips can still be
selected.


## Usage

On JRuby, **[`ImageProcessing::Java2D`]** provides the same chainable API using
the Java2D image APIs.

Processing is performed through **[`ImageProcessing::Vips`]** or
**[`ImageProcessing::MiniMagick`]** modules. Both modules share the same
chainable API for defining the processing pipeline:
Expand Down Expand Up @@ -155,6 +163,7 @@ You can continue reading the API documentation for specific modules:

* **[`ImageProcessing::Vips`]**
* **[`ImageProcessing::MiniMagick`]**
* **[`ImageProcessing::Java2D`]** (JRuby only; no additional dependency)

See the **[wiki]** for additional "How To" guides for common scenarios. The wiki
is publicly editable, so you're encouraged to add your own guides.
Expand Down Expand Up @@ -219,6 +228,7 @@ The `ImageProcessing::MiniMagick` functionality was extracted from
[GraphicsMagick]: http://www.graphicsmagick.org
[`ImageProcessing::Vips`]: doc/vips.md#readme
[`ImageProcessing::MiniMagick`]: doc/minimagick.md#readme
[`ImageProcessing::Java2D`]: doc/java2d.md#readme
[refile-mini_magick]: https://github.com/refile/refile-mini_magick
[wiki]: https://github.com/janko/image_processing/wiki
[HTTP.rb]: https://github.com/httprb/http
Expand Down
39 changes: 39 additions & 0 deletions doc/java2d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# ImageProcessing::Java2D

`ImageProcessing::Java2D` is a JRuby image processor implemented with the JDK's
ImageIO and Java2D APIs. It has no native library or additional gem dependency.
MiniMagick and Vips remain available on JRuby and are not replaced automatically.

## Usage

```rb
require "image_processing/java2d"

processed = ImageProcessing::Java2D
.source(image)
.resize_to_limit(400, 400)
.convert("png")
.call
```

In Rails, select it with `config.active_storage.variant_processor = :java2d`.
The canonical Ruby API remains `ImageProcessing::Java2D`.

The processor implements `resize_to_limit`, `resize_to_fit`, `resize_to_fill`,
`resize_and_pad`, `resize_to_cover`, `crop`, `rotate`, `flip`, `composite`, and
`strip`. JPEG EXIF orientation is applied on load by default; pass
`loader(auto_orient: false)` to retain the stored orientation.

The Java2D-specific operation keywords are `gravity` on `resize_to_fill`,
`background` and `gravity` on `resize_and_pad`, `background` on `rotate`, and
`mode`, `gravity`, and `offset` on `composite`. Other operation keywords are
rejected instead of being silently ignored.

Image formats are limited to the ImageIO readers and writers installed in the
JVM. Standard JDKs include JPEG, PNG, GIF, BMP, and WBMP. The `saver` options
are `quality` (either `0.0..1.0` or `0..100`), `saver` for an explicit ImageIO
format name, and `background` for flattening transparent images to JPEG.

`composite` supports the `over`, `src`, `clear`, and `dest-over` modes. Java2D
does not provide equivalents for every ImageMagick or libvips operation; use
`custom` to work directly with the `java.awt.image.BufferedImage` accumulator.
4 changes: 2 additions & 2 deletions image_processing.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Gem::Specification.new do |spec|

spec.required_ruby_version = ">= 3.0"

spec.summary = "High-level wrapper for processing images for the web with ImageMagick or libvips."
spec.description = "High-level wrapper for processing images for the web with ImageMagick or libvips."
spec.summary = "High-level wrapper for processing images for the web with ImageMagick or libvips. Supports Java2D on JRuby."
spec.description = "High-level wrapper for processing images for the web with ImageMagick or libvips. It also supports the Java2D image APIs on JRuby."
spec.homepage = "https://github.com/janko/image_processing"
spec.authors = ["Janko Marohnić"]
spec.email = ["janko.marohnic@gmail.com"]
Expand Down
3 changes: 3 additions & 0 deletions lib/image_processing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ def self.unsafe_method?(receiver, name)

autoload :MiniMagick, "image_processing/mini_magick"
autoload :Vips, "image_processing/vips"
autoload :Java2D, "image_processing/java2d"
# ActiveSupport camelizes the Rails processor name :java2d as Java2d.
autoload :Java2d, "image_processing/java2d"
end
Loading