web-dev-qa-db-ja.com

Javaで画像の一部の領域をどのようにトリミングしますか?

私は次のコードを実行しようとしています:

private void crop(HttpServletRequest request, HttpServletResponse response){
    int x = 100;
    int y = 100;
    int w = 3264;
    int h = 2448;

    String path = "D:images\\upload_final\\030311175258.jpg";

    BufferedImage image = ImageIO.read(new File(path));
    BufferedImage out = image.getSubimage(x, y, w, h);

    ImageIO.write(out, "jpg", new File(path));

}

しかし、私に同じエラーを出し続けます:

Java.awt.image.RasterFormatException: (x + width) is outside of Raster
Sun.awt.image.ByteInterleavedRaster.createWritableChild(ByteInterleavedRaster.Java:1230)
    Java.awt.image.BufferedImage.getSubimage(BufferedImage.Java:1156)

私の間違いはどこにありますか?

21
Valter Silva

私の最初の推測はあなたの(x + w) > image.getWidth()

Image.getWidth()を出力する場合、それは3264ですか? :O

あなたが現在していることはこれです:

<-- 3264 ------>
+--------------+
|    orig      | +-- Causing the problem
|              | V
|   +--------------+
|100| overlap  |   |
|   |          |   |
|   |          |   |
+---|----------+   |
    |              |
    |    out       |
    +--------------+

Origの上部コーナーをトリミングしようとしていて、「オーバーラップ」するだけの場合は、次のことを行う必要があります。

BufferedImage out = image.getSubimage(x, y, w-x, h-y);

これを行おうとしている場合:

+------------------+
|                  |
|  +-----------+   |
|  |           |   |
|  |           |   |
|  |           |   |
|  |           |   |
|  +-----------+   |
|                  |
+------------------+

次に、これを行う必要があります。

BufferedImage out = image.getSubimage(x, y, w-2*x, h-2*y);
33
corsiKa

ソフトウェアでトリミングやその他の基本的な画像操作機能が必要な場合は、画像処理ライブラリを使用することをお勧めします。通常、実装は最適化され、安定しています。

いくつかのJava画像処理ライブラリ: ImageJMarvinJMagick[〜#〜 ] jiu [〜#〜]JH Labsimgscalr

もう1つの利点は、物事をシンプルに保つことです。ほんの数行のコードで多くのことができます。以下の例では、トリミングに Marvin Framework を使用しました。

オリジナル:
enter image description here

トリミング:
enter image description here

出典:

MarvinImage image = MarvinImageIO.loadImage("./res/famousFace.jpg");
crop(image.clone(), image, 60, 32, 182, 62);
MarvinImageIO.saveImage(image, "./res/famousFace_cropped.jpg");