web-dev-qa-db-ja.com

ImageIO.write jpgファイルの使用に関する問題:ピンクの背景

次のコードを使用してjpgファイルを記述しています。

String url="http://img01.taobaocdn.com/imgextra/i1/449400070/T2hbVwXj0XXXXXXXXX_!!449400070.jpg";
String to="D:/temp/result.jpg";
ImageIO.write(ImageIO.read(new URL(url)),"jpg", new File(to));

しかし、私はresult.jpgはピンクの背景画像です。

alt text

47
Koerr

これを回避するには、デコードアルゴリズムの異なる実装を使用するToolkit.createImage(url)の代わりにImageIO.read(url)を使用します。

Sun JDKに含まれているJPEGエンコーダーを使用している場合は、アルファチャンネルのない画像を渡す必要があります。

例:

_private static final int[] RGB_MASKS = {0xFF0000, 0xFF00, 0xFF};
private static final ColorModel RGB_OPAQUE =
    new DirectColorModel(32, RGB_MASKS[0], RGB_MASKS[1], RGB_MASKS[2]);

    // ...

String sUrl="http://img01.taobaocdn.com/imgextra/i1/449400070/T2hbVwXj0XXXXXXXXX_!!449400070.jpg";
URL url = new URL(sUrl);
Image img = Toolkit.getDefaultToolkit().createImage(url);

PixelGrabber pg = new PixelGrabber(img, 0, 0, -1, -1, true);
pg.grabPixels();
int width = pg.getWidth(), height = pg.getHeight();

DataBuffer buffer = new DataBufferInt((int[]) pg.getPixels(), pg.getWidth() * pg.getHeight());
WritableRaster raster = Raster.createPackedRaster(buffer, width, height, width, RGB_MASKS, null);
BufferedImage bi = new BufferedImage(RGB_OPAQUE, raster, false, null);

String to = "D:/temp/result.jpg";
ImageIO.write(bi, "jpg", new File(to));
_

注:私の推測では、カラープロファイルは破損しており、Toolkit.createImage()はすべてのカラープロファイルを無視します。その場合、これにより、正しいカラープロファイルを持つJPEGの品質が低下します。

38
finnw

同様の問題がありました。しかし、私はこれを使用して解決しました

   BufferedImage image = new BufferedImage(width, height,
            BufferedImage.TYPE_INT_RGB); 

   //do something to populate the image
   //such as
   image.setRGB( x, y, pixelValue); //set your own pixels color



   ImageIO.write(image, "jpg", new File("D:\\test.jpg"));

私がJavaバージョン1.6.0_25-b06を使用していることに注意してください。正常に動作します。

Javaバージョン。

19
Wen

これは私のために働く:

int w = originalImage.getWidth();
int h = originalImage.getHeight();
BufferedImage newImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
int[] rgb = originalImage.getRGB(0, 0, w, h, null, 0, w);
newImage.setRGB(0, 0, w, h, rgb, 0, w);
12
  • 私にとって問題は読書ではなく、執筆でした
  • ImageIOはARGB BufferedImagesからJPGファイルを喜んで書き込みます
  • ブラウザー/他のプログラムは、この4チャンネルファイルをCMYKカラーなどとして解釈し、この質問で説明されている効果をもたらします。
  • ソリューション私にとって:ImageIO.writeに渡されるBufferedImageがRGBタイプ(ARGBではない)であることを確認してください
  • これは、jpegへの保存時にのみ問題が表示される理由を説明しますが、pngへの保存時には表示されません。
  • 私の画像ツールは常にオンザフライでARGBに変換されるため、これを理解するのに長い時間がかかりました。
1
Reto Höhener

ImageIOを使用して画像を読み書きするときに同じ問題に直面しました。ここで回答を読んだ後、JREを変更しました-openjdk version "1.8.0_91"からHotSpot Java version "1.8.0_102"。ヒントはfinnwの回答では明らかではありませんでしたが、試してみる価値はあります;-)

したがって、問題は解決しました!したがって、OpenJDK JREを使用していて、JREを自由に変更できる場合、HotSpotを変更すれば、コードを変更する必要はありません。

1
Bazi
BufferedImage originalImage = ImageIO.read(getContent());
BufferedImage newImage = new BufferedImage(originalImage.getWidth(), originalImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR);

    for (int x = 0; x < originalImage.getWidth(); x++) {
        for (int y = 0; y < originalImage.getHeight(); y++) {
            newImage.setRGB(x, y, originalImage.getRGB(x, y));
        }
    }

これは私のためにトリックをしました

1
hans moleman