TwelveMonkeys ImageIO は、 javax.imageio.*
パッケージのプラグインを通じて、Java プラットフォームに拡張画像ファイル形式のサポートを提供します。
このプロジェクトの主な目標は、JDK でカバーされていないファイル形式のサポートを提供することです。これらの形式のサポートは、「実際に存在する」データを読み取ることができるようにするため、またレガシー形式のデータへのアクセスを維持するために重要です。レガシー データが大量に存在するため、一般的な形式のリーダーのオープン実装の必要性が認識されています。
プラグイン | 形式 | 説明 | R | W | メタデータ | 注意事項 |
---|---|---|---|---|---|---|
バティック | SVG | スケーラブルなベクター グラフィックス | ✔ | - | - | バティックが必要です |
WMF | MS Windows メタファイル | ✔ | - | - | バティックが必要です | |
BMP | BMP | MS Windows および IBM OS/2 デバイスに依存しないビットマップ | ✔ | ✔ | ネイティブ、スタンダード | |
カール | MS Windows のカーソル形式 | ✔ | - | - | ||
ICO | MS Windows アイコン形式 | ✔ | ✔ | - | ||
DDS | DDS | MS ダイレクト描画サーフェス フォーマット | ✔ | - | 標準 | |
HDR | HDR | ラディアンス ハイ ダイナミック レンジ RGBE フォーマット | ✔ | - | 標準 | |
ICNS | ICNS | アップルのアイコン画像 | ✔ | ✔ | - | |
IFF | IFF | Commodore Amiga/Electronic Arts Interchange ファイル形式 | ✔ | ✔ | 標準 | |
JPEG | JPEG | 共同写真家専門家グループ | ✔ | ✔ | ネイティブ、スタンダード | |
JPEGロスレス | ✔ | - | ネイティブ、スタンダード | |||
PCX | PCX | ZSoft ペイントブラシ形式 | ✔ | - | 標準 | |
DCX | 複数ページの PCX FAX 文書 | ✔ | - | 標準 | ||
ピクト | ピクト | Apple QuickTime 画像フォーマット | ✔ | ✔ | 標準 | |
PNTG | Apple MacPaint の画像形式 | ✔ | - | 標準 | ||
PNM | パム | NetPBM ポータブル任意のマップ | ✔ | ✔ | 標準 | |
PBM | NetPBM ポータブル ビット マップ | ✔ | - | 標準 | ||
PGM | NetPBM ポータブル グレー マップ | ✔ | - | 標準 | ||
PPM | NetPBM ポータブル ピックス マップ | ✔ | ✔ | 標準 | ||
PFM | ポータブルフロートマップ | ✔ | - | 標準 | ||
PSD | PSD | Adobe Photoshop ドキュメント | ✔ | (✔) | ネイティブ、スタンダード | |
PSB | Adobe Photoshop の大きなドキュメント | ✔ | - | ネイティブ、スタンダード | ||
SGI | SGI | シリコングラフィックス画像フォーマット | ✔ | - | 標準 | |
TGA | TGA | Truevision TGA 画像フォーマット | ✔ | ✔ | 標準 | |
親指DB | 親指.db | MS Windows 親指 DB | ✔ | - | - | OLE2 複合ドキュメントベースの形式のみ |
TIFF | TIFF | Aldus/Adobe タグ付き画像ファイル形式 | ✔ | ✔ | ネイティブ、スタンダード | |
BigTIFF | ✔ | ✔ | ネイティブ、スタンダード | |||
WebP | WebP | Google WebP形式 | ✔ | - | 標準 | |
XWD | XWD | X11 ウィンドウ ダンプ フォーマット | ✔ | - | 標準 |
Batik を使用する際の重要な注意事項: 「Apache™ XML グラフィックス プロジェクト - セキュリティ」を読み、更新された安全なバージョンを使用していることを確認してください。
GIF、PNG、および WBMP 形式は、JDK 標準プラグインを使用して ImageIO API を通じてすでにサポートされていることに注意してください。 BMP、JPEG、および TIFF 形式の場合、TwelveMonkeys プラグインは拡張形式のサポートと追加機能を提供します。
ほとんどの場合、必要なのはプロジェクトにプラグインを含めて次のように記述するだけです。
BufferedImage image = ImageIO . read ( file );
これにより、ファイルの最初のイメージが完全にメモリにロードされます。
基本的で最も単純な書き方は次のとおりです。
if (! ImageIO . write ( image , format , file )) {
// Handle image not written case
}
これにより、指定された形式のデフォルト設定を使用して、画像全体が 1 つのファイルに書き込まれます。
プラグインは実行時に自動的に検出されます。このメカニズムの仕組みの詳細については、FAQ を参照してください。
読み取りパラメータと読み取りプロセスをより詳細に制御する必要がある場合、読み取りに関する一般的な表現は次のようなものになります。
// Create input stream (in try-with-resource block to avoid leaks)
try ( ImageInputStream input = ImageIO . createImageInputStream ( file )) {
// Get the reader
Iterator < ImageReader > readers = ImageIO . getImageReaders ( input );
if (! readers . hasNext ()) {
throw new IllegalArgumentException ( "No reader for: " + file );
}
ImageReader reader = readers . next ();
try {
reader . setInput ( input );
// Optionally, listen for read warnings, progress, etc.
reader . addIIOReadWarningListener (...);
reader . addIIOReadProgressListener (...);
ImageReadParam param = reader . getDefaultReadParam ();
// Optionally, control read settings like sub sampling, source region or destination etc.
param . setSourceSubsampling (...);
param . setSourceRegion (...);
param . setDestination (...);
// ...
// Finally read the image, using settings from param
BufferedImage image = reader . read ( 0 , param );
// Optionally, read thumbnails, meta data, etc...
int numThumbs = reader . getNumThumbnails ( 0 );
// ...
}
finally {
// Dispose reader in finally block to avoid memory leaks
reader . dispose ();
}
}
最初に画像全体をメモリに読み込まずに、 reader.getWidth(n)
とreader.getHeight(n)
を使用して、ソース画像の寸法をリーダーにクエリします。
reader.getNumImages()
を使用して、ループ内で同じファイルから複数の画像を読み取ることもできます。
書き込みパラメータと書き込みプロセスをより詳細に制御する必要がある場合、書き込みの一般的な表現は次のようなものになります。
// Get the writer
Iterator < ImageWriter > writers = ImageIO . getImageWritersByFormatName ( format );
if (! writers . hasNext ()) {
throw new IllegalArgumentException ( "No writer for: " + format );
}
ImageWriter writer = writers . next ();
try {
// Create output stream (in try-with-resource block to avoid leaks)
try ( ImageOutputStream output = ImageIO . createImageOutputStream ( file )) {
writer . setOutput ( output );
// Optionally, listen to progress, warnings, etc.
ImageWriteParam param = writer . getDefaultWriteParam ();
// Optionally, control format specific settings of param (requires casting), or
// control generic write settings like sub sampling, source region, output type etc.
// Optionally, provide thumbnails and image/stream metadata
writer . write (..., new IIOImage (..., image , ...), param );
}
}
finally {
// Dispose writer in finally block to avoid memory leaks
writer . dispose ();
}
より高度な使用法と ImageIO API の使用方法については、Oracle の『Java Image I/O API Guide』を読むことをお勧めします。
import com . twelvemonkeys . imageio . path . Paths ;
...
try ( ImageInputStream stream = ImageIO . createImageInputStream ( new File ( "image_with_path.jpg" )) {
BufferedImage image = Paths . readClipped ( stream );
// Do something with the clipped image...
}
詳細とサンプルコードについては、Wiki の「Adobe Clipping Path support」を参照してください。
このライブラリにはリサンプリング (画像のサイズ変更) 操作が付属しており、適切な速度で優れた結果を提供するためのさまざまなアルゴリズムが含まれています。
import com . twelvemonkeys . image . ResampleOp ;
...
BufferedImage input = ...; // Image to resample
int width , height = ...; // new width/height
BufferedImageOp resampler = new ResampleOp ( width , height , ResampleOp . FILTER_LANCZOS ); // A good default filter, see class documentation for more info
BufferedImage output = resampler . filter ( input , null );
このライブラリにはディザリング操作が付属しており、Floyd-Steinberg 誤差拡散ディザを使用してBufferedImage
をIndexColorModel
に変換するために使用できます。
import com . twelvemonkeys . image . DiffusionDither ;
...
BufferedImage input = ...; // Image to dither
BufferedImageOp ditherer = new DiffusionDither ();
BufferedImage output = ditherer . filter ( input , null );
通常のパターンを使用してイメージをロードする場合、破損したイメージをロードしようとすると、 IOException
がスローされます。
BufferedImage image = null ;
try {
image = ImageIO . read ( file );
} catch ( IOException exception ) {
// Handle, log a warning/error etc
}
このシナリオでは、イメージが破損し、 ImageIO.read
例外をスローした場合、 image
null
ままです。関数が値を返しながら例外をスローすることは不可能です。
ただし、場合によっては、破損した画像から使用可能な画像データを取得できる場合もあります。これを行う方法は、 ImageReadParam
使用してBufferedImage
宛先として設定することです。
int width = reader . getWidth ( 0 );
int height = reader . getHeight ( 0 );
ImageTypeSpecifier imageType = reader . getRawImageType ( 0 );
BufferedImage image = imageType . createBufferedImage ( width , height );
ImageReadParam param = reader . getDefaultReadParam ();
param . setDestination ( image );
try {
reader . read ( 0 , param );
}
catch ( IOException e ) {
// Handle, log a warning/error etc
}
理論的には、これはすべてのプラグインで機能するはずですが、結果はプラグイン/実装に大きく依存します。一部の形式および一部の形式の破損したファイルでは、ほとんど役立つ画像が得られる場合があります。ただし、空白または空のイメージが表示されるだけの可能性があることを覚悟しておく必要があります。
プロジェクトをダウンロードします (Git を使用):
$ git clone [email protected]:haraldk/TwelveMonkeys.git
これにより、現在のディレクトリにTwelveMonkeys
という名前のフォルダーが作成されます。ディレクトリをTwelveMonkeys
フォルダーに変更し、以下のコマンドを実行してビルドします。
プロジェクトをビルドします (Maven を使用)。
$ mvn package
現在、ビルドの作成に推奨される JDK は Oracle JDK 8.x です。
OpenJDK を使用してビルドすることは可能ですが、使用されるカラー管理システム間のわずかな違いにより、一部のテストが失敗する可能性があります。問題のテストを無効にするか、テストをまったく行わずにビルドする必要があります。
単体テストの実行にはかなりのメモリが必要なため、環境変数MAVEN_OPTS
を設定して、Maven を実行する Java プロセスにより多くのメモリを与える必要がある場合があります。 -Xmx512m -XX:MaxPermSize=256m
のようなものをお勧めします。
オプションで、以下を使用してローカル Maven リポジトリにプロジェクトをインストールできます。
$ mvn install
プラグインをインストールするには、Maven を使用して必要な依存関係をプロジェクトに追加するか、必要な JAR を必要な依存関係とともにクラスパスに手動で追加します。
ImageIO レジストリとサービス検索メカニズムにより、プラグインが使用できるかどうかが確認されます。
JPEG プラグインがインストールされ、実行時に使用されていることを確認するには、次のコードを使用できます。
Iterator < ImageReader > readers = ImageIO . getImageReadersByFormatName ( "JPEG" );
while ( readers . hasNext ()) {
System . out . println ( "reader: " + readers . next ());
}
最初の行には次のように出力されます。
reader: com.twelvemonkeys.imageio.plugins.jpeg.JPEGImageReader@somehash
Maven を使用して JPEG および TIFF プラグインに依存するには、以下を POM に追加します。
...
< dependencies >
...
< dependency >
< groupId >com.twelvemonkeys.imageio</ groupId >
< artifactId >imageio-jpeg</ artifactId >
< version >3.12.0</ version >
</ dependency >
< dependency >
< groupId >com.twelvemonkeys.imageio</ groupId >
< artifactId >imageio-tiff</ artifactId >
< version >3.12.0</ version >
</ dependency >
<!--
Optional dependency. Needed only if you deploy ImageIO plugins as part of a web app.
Make sure you add the IIOProviderContextListener to your web.xml, see above.
-->
< dependency >
< groupId >com.twelvemonkeys.servlet</ groupId >
< artifactId >servlet</ artifactId >
< version >3.12.0</ version >
</ dependency >
<!--
Or Jakarta version, for Servlet API 5.0
-->
< dependency >
< groupId >com.twelvemonkeys.servlet</ groupId >
< artifactId >servlet</ artifactId >
< version >3.12.0</ version >
< classifier >jakarta</ classifier >
</ dependency >
</ dependencies >
IDE またはプログラムの JPEG および TIFF プラグインに依存するには、次のすべての JAR をクラスパスに追加します。
twelvemonkeys-common-lang-3.12.0.jar
twelvemonkeys-common-io-3.12.0.jar
twelvemonkeys-common-image-3.12.0.jar
twelvemonkeys-imageio-core-3.12.0.jar
twelvemonkeys-imageio-metadata-3.12.0.jar
twelvemonkeys-imageio-jpeg-3.12.0.jar
twelvemonkeys-imageio-tiff-3.12.0.jar
ImageIO
プラグイン レジストリ ( IIORegistry
) は「VM グローバル」であるため、そのままではサーブレット コンテキストでは適切に動作しません。これはWEB-INF/lib
またはclasses
フォルダーからプラグインをロードする場合に特に顕著です。コードのどこかにImageIO.scanForPlugins()
を追加しない限り、プラグインはまったく利用できない可能性があります。
さらに、サーブレット コンテキストは、クラスを動的にロードおよびアンロードします (コンテキストごとに新しいクラス ローダーを使用します)。アプリケーションを再起動すると、古いクラスはデフォルトでメモリ内に永久に残ります (次回scanForPlugins
が呼び出されるときは、別のClassLoader
がクラスをスキャン/ロードするため、レジストリ内の新しいインスタンスになるためです)。残りの「古い」リーダーの 1 つを使用して読み取りを試行すると、奇妙な例外 ( static final
初期化フィールドにアクセスするときのNullPointerException
や、初期化されていない内部クラスのNoClassDefFoundError
など) が発生する可能性があります。
検出の問題とリソース リークの両方を回避するには、Web アプリケーションの ImageIO プラグインの動的なロードとアンロードを実装するIIOProviderContextListener
使用することを強くお勧めします。
< web-app ...>
...
< listener >
< display-name >ImageIO service provider loader/unloader</ display-name >
< listener-class >com.twelvemonkeys.servlet.image.IIOProviderContextListener</ listener-class >
</ listener >
...
</ web-app >
コンテキスト リスナーがインストールされていない状態でWEB-INF/lib
からプラグインをロードすることはサポートされておらず、正しく動作しません。
コンテキスト リスナーは TwelveMonkeys ImageIO プラグインへの依存関係がなく、JAI ImageIO または他の ImageIO プラグインでも使用できます。
もう 1 つの安全なオプションは、アプリケーション サーバーの共有または共通の lib フォルダーに JAR ファイルを配置することです。
古いjavax.servlet
から新しいjakarta.servlet
パッケージに移行する場合は、別の依存関係を使用できます。これには、上で説明したものとまったく同じサーブレット クラスが含まれていますが、新しい Jakarta EE パッケージに対して構築されています。依存関係には以前と同じグループ名と識別子が付いていますが、非 Jakarta パッケージと区別するために、 jakarta
分類子が追加されています。
Maven で有効にする方法については、Maven の依存関係の例を参照してください。 Gradle または他のビルド ツールにも同様のオプションがあります。
プラグインの推奨される使用方法は、Maven 依存関係などを介して JAR をそのままプロジェクトに含めることです。ライブラリを使用するために再パッケージ化する必要はなく、推奨されません。
ただし、「ファット」JAR を作成したい場合、または何らかの理由で JAR を再パッケージ化したい場合は、ImageIO によるプラグインの自動検出がサービス プロバイダー インターフェイス (SPI) メカニズムに依存していることを覚えておくことが重要です。つまり、各 JAR には、1 つ以上のファイル (通常はjavax.imageio.spi.ImageReaderSpi
およびjavax.imageio.spi.ImageWriterSpi
) を含むMETA-INF/services
という名前の特別なフォルダが含まれています。これらのファイルはすべての JAR に同じ名前で存在するため、すべてを 1 つのフォルダーに解凍するか、JAR を作成するだけでは、ファイルは上書きされ、動作は不定になります (ほとんどの場合、インストールされるプラグインは 1 つだけになります)。
解決策は、同じ名前のすべてのファイルを、各タイプのすべての SPI 情報を含む 1 つのファイルにマージすることです。 Maven Shade プラグインを使用している場合は、ServicesResourceTransformer を使用してこれらのファイルを適切にマージする必要があります。また、ManifestResourceTransforme を使用して、正しいベンダー名、バージョン情報などを取得することもできます。他の「ファット」JAR バンドラーには、同じ名前のエントリをマージする同様のメカニズムがある可能性があります。
Java 7 で動作する最新バージョンは 3.9.4 です。それ以降のバージョンでは Java 8 以降が必要になります。
一般的な依存関係
ImageIO の依存関係
ImageIO プラグイン
サードパーティのライブラリを必要とする ImageIO プラグイン
ImageIO の Photoshop パスのサポート
サーブレットのサポート
このプロジェクトは、OSI 承認の BSD ライセンスに基づいて提供されます。
Copyright (c) 2008-2022, Harald Kuhr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
o Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
o Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
q:どうやって使うのですか?
a: 最も簡単な方法は、Maven、Gradle、または依存関係管理を備えたその他のビルド ツールを使用して独自のプロジェクトを構築し、必要な特定のプラグインに依存関係を追加するだけです。このようなビルド ツールを使用しない場合は、必要な JAR がすべてクラスパスにあることを確認してください。上記の「インストール」セクションを参照してください。
Q: プラグインを使用するには、コードにどのような変更を加える必要がありますか?
a: 簡単に言うと、「なし」です。 ImageIO.read(...)
やImageIO.getImageReaders(...)
などの基本的な使用法では、コードを変更する必要はありません。ほとんどの機能は標準の ImageIO API を通じて利用でき、必要のない余分な API を導入しないように細心の注意が払われています。
一部の形式の非常に特殊な高度な機能を使用したい場合は、複数のファイルで構成される SVG 画像のベース URL を設定したり、TIFF ファイルの出力圧縮を制御したりするなど、特定の API を使用する必要がある場合があります。
q: どのように機能しますか?
a: TwelveMonkeys ImageIO プロジェクトには、ImageIO のプラグインが含まれています。 ImageIO はサービス検索メカニズムを使用して、実行時にプラグインを検出します。
必要なのは、クラスパスに TwelveMonkeys ImageIO JAR があることを確認することだけです。
レジストリと検索メカニズムの詳細については、IIORegistry API ドキュメントを参照してください。
細かい点: JPEG、BMP、および TIFF の TwelveMonkeys サービス プロバイダは、onRegistration メソッドをオーバーライドし、 IIOServiceRegistry
のペアごとの部分順序付けメカニズムを利用して、Sun/Oracle が提供するJPEGImageReader
、 BMPImageReader
TIFFImageReader
、および Apple が提供する前にインストールされるようにします。 OS X ではそれぞれTIFFImageReader
が提供されました。ペアごとの順序付けを使用しても、これらの実装から機能が削除されることはありませんが、ほとんどの場合、代わりに TwelveMonkeys プラグインを使用することになります。
q: GIF や PNG などの一般的な形式がサポートされていないのはなぜですか?
a: 簡単に言うと、これらの形式に対する ImageIO の組み込みサポートは現状のままで十分であると考えられているということです。 Java 7 および 8 での PNG 書き込みパフォーマンスの向上をお探しの場合は、「JDK9 PNG Writer Backport」を参照してください。
q: 次のリリースはいつですか?現在のリリーススケジュールは何ですか?
a: 目標は、バグ修正とマイナーな新機能を含む毎月のリリースを作成することです。そして、より多くの「主要な」機能を備えた四半期ごとのリリース。
q: このプロジェクトが大好きです!どうすれば助けられますか?
a: 未解決の問題を調べて、修正に役立つ問題があるかどうかを確認したり、サンプル ファイルを提供したり、テスト ケースを作成したりできます。 GitHub スポンサーを通じて、あなたまたはあなたの組織がスポンサーになることも可能です。資金を提供していただくことで、バグの修正や新機能の実装により多くの時間を費やすことができます。
Q:JAIはどうですか?いくつかの形式はすでに JAI によってサポートされています。
a: JAI (特に jai-imageio) は同じ形式の一部をサポートしていますが、JAI にはいくつかの大きな問題があります。最も明白なことは次のとおりです。
Q: JMagick や IM4Java についてはどうですか?すでにあるものをそのまま使うことはできないのでしょうか?
a: 幅広い形式をサポートする優れたライブラリですが、ImageMagick ベースのライブラリには ImageIO と比較していくつかの欠点があります。
やりました