Создание мозаики с Джай - PullRequest
       8

Создание мозаики с Джай

1 голос
/ 16 сентября 2011

Я пытаюсь объединить несколько изображений в одно, но у меня возникли проблемы. Чтобы изолировать это, я создал следующий POC, который я пытаюсь решить, чтобы понять, как использовать JAI API.

В POC у меня есть два изображения "image1.gif" и "image2.gif", которые оба имеют размер 256x256. Цель состоит в том, чтобы объединить их горизонтально в одно изображение "image3.png", которое имеет размер 512x256. Вот код, который я написал для этого, используя JAI.

try {
    InputStream stream1 = new FileInputStream("D:\\poc\\image1.gif");
    InputStream stream2 = new FileInputStream("D:\\poc\\image2.gif");
    RenderedImage image1 = ImageIO.read(stream1);
    RenderedImage image2 = ImageIO.read(stream2);
    ImageLayout imageLayout = new ImageLayout(0,0,512,256);
    RenderingHints renderingHints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, imageLayout);
    RenderedImage finalImage = MosaicDescriptor.create(new RenderedImage[]{image1, image2}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
    FileStoreDescriptor.create(finalImage, "D:\\poc\\image3.png", "PNG", null, null, null);
} catch (FileNotFoundException e) {
    e.printStackTrace();
    return;
} catch (IOException e) {
    e.printStackTrace();
    return;
}

Я получаю изображение правильных размеров 512x256, причем первое изображение (image1) полностью в левой части изображения, а правая часть изображения полностью черная. Другими словами, это как будто я конкатенировал image1.gif с черным квадратом 256x256.

Я попытался изменить MosaicType на MosaicDescriptor.MOSAIC_TYPE_BLEND, но это просто создает похожее изображение, только левая половина состоит из image1, наложенного поверх image2 (или наоборот), а правая половина все еще полностью черная.

Я также попытался изменить первые два параметра конструктора ImageLayout. Это тоже не работает - например, я могу установить первый параметр ImageLayout равным -256, но затем в правой половине изображения будет показано изображение 1, а в левой половине - черный.

Пожалуйста, помогите!

Ответы [ 2 ]

0 голосов
/ 11 декабря 2014

Вот более краткий способ мозаики двух изображений с использованием JAI. Основной процесс состоит в том, чтобы переводить (или деформировать) исходные изображения в общее пространство изображений мозаики. Затем вы можете предоставить все переведенные изображения для операции мозаики. Там нет необходимости выполнять две операции мозаики. Поскольку объединение пространств изображений всех входных изображений соответствует требуемому пространству выходного изображения мозаики, вам не нужно указывать ImageLayout в качестве RenderingHint. В этом примере входные изображения создаются в памяти, но их можно прочитать из файла, как это сделано в оригинальном сообщении.

   public void makeMosaic(String fileName) throws IOException{
        // Make a black image in memory
        RenderedImage blackImage = ConstantDescriptor.create(256f,256f,new Byte[]{0x00,0x00,0x00},null);
        // Make a white image in memory
        RenderedImage whiteImage = ConstantDescriptor.create(256f, 256f, new Byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff},null);
        // Translate the white image to shift it 256 pixels to the right
        RenderedImage translatedWhiteImage = TranslateDescriptor.create(whiteImage, 256f, 0f, new InterpolationNearest(), null);
        // Now you can mosaic the two images.  No need to supply an ImageLayout hint or pre-mosaic the black image.
        RenderedImage mosaic = MosaicDescriptor.create(new RenderedImage[]{blackImage,translatedWhiteImage}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, null);
        // Write out the output image.  Should be 256 pixels tall and 512 pixels wide with black tile on left and white tile on right.
        ImageIO.write(mosaic, "PNG", new File(fileName));
    }
0 голосов
/ 19 сентября 2011

Вот окончательное решение, которое я придумал - эти общие методы создают мозаики из двух изображений для иллюстрации.Вам просто нужно сопоставить их с общим пространством координат - сначала создайте мозаику из одного изображения (чтобы увеличить общий размер, так как ScaleDescriptor по какой-то причине не работает), а затем переведите второе, чтобы его можно было перекрытьпервый.

private static RenderedImage horizontalMosaic(RenderedImage image1, RenderedImage image2) {
    ImageLayout imageLayout = new ImageLayout(0, 0, image1.getWidth() + image2.getWidth(), image1.getHeight());
    RenderingHints renderingHints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, imageLayout);
    RenderedImage image3 = MosaicDescriptor.create(new RenderedImage[]{image1}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
    RenderedImage image4 = MosaicDescriptor.create(new RenderedImage[]{image2}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
    RenderedImage image5 = TranslateDescriptor.create(image4, (float)image1.getWidth(), 0.0f, null, renderingHints);
    return MosaicDescriptor.create(new RenderedImage[]{image3, image5}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
}

private static RenderedImage verticalMosaic(RenderedImage image1, RenderedImage image2) {
    ImageLayout imageLayout = new ImageLayout(0, 0, image1.getWidth(), image1.getHeight() + image2.getHeight());
    RenderingHints renderingHints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, imageLayout);
    RenderedImage image3 = MosaicDescriptor.create(new RenderedImage[]{image1}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
    RenderedImage image4 = MosaicDescriptor.create(new RenderedImage[]{image2}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
    RenderedImage image5 = TranslateDescriptor.create(image4, 0.0f, (float)image1.getHeight(), null, renderingHints);
    return MosaicDescriptor.create(new RenderedImage[]{image3, image5}, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, null, null, null, renderingHints);
}
...