Преобразование прозрачного gif / png к jpeg использование Java

20
задан Glorfindel 26 February 2019 в 11:01
поделиться

5 ответов

Проблема (по крайней мере, с png к jpg преобразованию) состоит в том, что цветовая схема не является тем же, потому что jpg не поддерживает прозрачность.

то, Что мы сделали успешно, является чем-то вдоль этих строк (это вытягивают от различных битов кода - поэтому простите грубость форматирования):

File file = new File("indexed_test.gif");
BufferedImage image = ImageIO.read(file);
int width = image.getWidth();
int height = image.getHeight();
BufferedImage jpgImage;

//you can probably do this without the headless check if you just use the first block
if (GraphicsEnvironment.isHeadless()) {
  if (image.getType() == BufferedImage.TYPE_CUSTOM) {
      //coerce it to  TYPE_INT_ARGB and cross fingers -- PNGs give a    TYPE_CUSTOM and that doesn't work with
      //trying to create a new BufferedImage
     jpgImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
  } else {
     jpgImage = new BufferedImage(width, height, image.getType());
  }
} else {
     jgpImage =   GraphicsEnvironment.getLocalGraphicsEnvironment().
        getDefaultScreenDevice().getDefaultConfiguration().
        createCompatibleImage(width, height, image.getTransparency()); 
}

//copy the original to the new image
Graphics2D g2 = null;
try {
 g2 = jpg.createGraphics();

 g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 
                    RenderingHints.VALUE_INTERPOLATION_BICUBIC);
 g2.drawImage(image, 0, 0, width, height, null);
}
finally {
   if (g2 != null) {
       g2.dispose();
   }
}

File f = new File("indexed_test.jpg");

ImageIO.write(jpgImage, "jpg", f);

Это работает на png к jpg и gif к jpg. И у Вас будет белый фон, где прозрачные биты были. Можно измениться, это при наличии g2 заполняет изображение другим цветом перед вызовом drawImage.

4
ответ дан 29 November 2019 в 22:45
поделиться

Как уже упомянуто в ОБНОВЛЕНИИ вопроса я реализовал более простой способ заменить прозрачные пиксели предопределенным цветом:

public static BufferedImage fillTransparentPixels( BufferedImage image, 
                                                   Color fillColor ) {
    int w = image.getWidth();
    int h = image.getHeight();
    BufferedImage image2 = new BufferedImage(w, h, 
        BufferedImage.TYPE_INT_RGB);
    Graphics2D g = image2.createGraphics();
    g.setColor(fillColor);
    g.fillRect(0,0,w,h);
    g.drawRenderedImage(image, null);
    g.dispose();
    return image2;
}

и я называю этот метод прежде jpeg преобразование таким образом:

if( inputImage.getColorModel().getTransparency() != Transparency.OPAQUE) {
    inputImage = fillTransparentPixels(inputImage, Color.WHITE);
}
10
ответ дан 29 November 2019 в 22:45
поделиться

JPEG не имеет никакой поддержки прозрачности. Таким образом, даже когда Вы получаете круговой цвет правильно, у Вас все еще будет черный или белый фон, в зависимости от Вашего кодера и/или рендерера.

2
ответ дан 29 November 2019 в 22:45
поделиться

с опозданием на 3 месяца, но у меня очень похожая проблема (хотя я даже не загружаю гифку, а просто генерирую прозрачное изображение - скажем, без фона, цветную форму - где при сохранении в jpeg, перепутаны все цвета, не только фон)

Нашел этот фрагмент кода в этой довольно старой ветке списка интересов java2d , подумал, что поделюсь, потому что после быстрого теста , оно намного более производительно, чем ваше решение:

        final WritableRaster raster = img.getRaster();
        final WritableRaster newRaster = raster.createWritableChild(0, 0, img.getWidth(), img.getHeight(), 0, 0, new int[]{0, 1, 2});

        // create a ColorModel that represents the one of the ARGB except the alpha channel
        final DirectColorModel cm = (DirectColorModel) img.getColorModel();
        final DirectColorModel newCM = new DirectColorModel(cm.getPixelSize(), cm.getRedMask(), cm.getGreenMask(), cm.getBlueMask());

        // now create the new buffer that we'll use to write the image
        return new BufferedImage(newCM, newRaster, false, null);

К сожалению, я не могу сказать, что понимаю в точности , что оно делает;)

4
ответ дан 29 November 2019 в 22:45
поделиться

Для Java 6 (и, я думаю, 5 тоже):

BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
g = bufferedImage.createGraphics();
//Color.WHITE estes the background to white. You can use any other color
g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, null);
42
ответ дан 29 November 2019 в 22:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: