Сделать оба BufferedImages перекрывающимися и прозрачными

Итак, я искал этот вопрос и получил много ответов, и поэтому я смог придумать код, показанный ниже. Я беру изображения из ImageStack (ImageJ) и хочу перекрыть два изображения в формате dicom (.dcm). Моя проблема в том, что я хочу, чтобы оба изображения были прозрачными, поскольку они перекрывают друг друга. Я проверил, что изображения отличаются при переходе к функции перекрытия, и я пробовал много вещей, но я не могу сделать изображения прозрачными, они перекрываются, но они не прозрачны. Любая помощь будет принята с благодарностью.

  public BufferedImage overlay(BufferedImage bii, BufferedImage biii){
            BufferedImage combined = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
            Graphics2D go = combined.createGraphics();
            image.setSlice(5);
            ImagePlus hello = new ImagePlus();
            hello.setImage(image.getImage());
            BufferedImage bello = hello.getBufferedImage();
            go.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            go.drawImage(bii,0, 0, null);
            go.drawImage(biii,98, 98, null);
            go.setComposite(AlphaComposite.Clear); 
            go.setComposite(AlphaComposite.Src);
            //go.fillRect(0, 0, 256, 256);
            go.dispose();
            return combined;
        }

Основная функция:

        ImageStack stack = image.getStack(); 
        Calibration cal = image.getCalibration(); 
        ImagePlus newImp = new ImagePlus( );
        stack.getSliceLabel(5);
        stack.getProcessor(5); 
        newImp.setCalibration( cal ); 
        ImageProcessor ip = stack.getProcessor(1); // specify number of slice 
        newImp.setProcessor(ip); 


        ImagePlus no3 = new ImagePlus();
        no3.setImage(newImp.getImage());
        BufferedImage bii= no3.getBufferedImage();

        ImagePlus bob = new ImagePlus( );
        stack.getSliceLabel(33);
        stack.getProcessor(33); 
        bob.setCalibration( cal ); 
        ImageProcessor bobp = stack.getProcessor(22); // specify number of slice 
        bob.setProcessor(bobp); 
        ImagePlus hello = new ImagePlus();
        hello.setImage(bob.getImage());
        BufferedImage bello = hello.getBufferedImage();

        BufferedImage overlayy = overlay(bii, bello);
        frame2 = new NFrame(image.getTitle(), image, save);
        JPanel pane = new JPanel(new BorderLayout());
        JLabel jLabel = new JLabel(new ImageIcon(overlayy));
        pane.add(jLabel);
        frame2.add(pane);
        frame2.setVisible(true);
        desktop.add(frame2);

person New Programmer    schedule 16.07.2014    source источник


Ответы (1)


ImageJ 1.x имеет только ограниченную поддержку прозрачных (ARGB) цветных изображений (например, см. " rel="nofollow noreferrer">здесь).

Один из способов изменить альфа-канал изображения ARGB — использовать методы getChannel и setChannel из ij.process.ColorProcessor. В качестве примера см. этот скрипт BeanShell.

Более простой способ объединить два изображения путем наложения одного изображения поверх другого изображения с определенной непрозрачностью — использовать оверлеи. Следующий скрипт BeanShell (перенос его на Java должен быть простым) является минимальным примером, демонстрирующим полупрозрачную комбинацию два изображения:

import ij.IJ;
import ij.gui.ImageRoi;
import ij.gui.Overlay;

imp = IJ.openImage("http://imagej.nih.gov/ij/images/leaf.jpg");
imp2 = IJ.openImage("http://imagej.nih.gov/ij/images/clown.jpg");

ImageRoi roi = new ImageRoi(50, 200, imp2.getProcessor());
roi.setZeroTransparent(false);
roi.setOpacity(0.5);
ovl = new Overlay(roi);

imp.setOverlay(ovl);
imp.show();

Вы можете попробовать скрипт, вставив код в редактор скриптов Fiji, выбрав Language > Beanshell и нажмите Выполнить.

Это будет результат:

Результат запуска скрипта beanshell

Чтобы экспортировать/сохранить изображение, вы должны запустить команду Image > Overlay > Flatten или, в Java/Beanshell:

flattenedImp = imp.flatten();
person Jan Eglinger    schedule 17.07.2014
comment
Я попробовал то, что вы сделали, но это не сделало изображение прозрачным. Та же проблема все еще существует. - person New Programmer; 17.07.2014
comment
Я добавил изображение, иллюстрирующее ожидаемый результат моего скрипта. Разве это не то, что вы получаете при запуске кода beanshell выше? - person Jan Eglinger; 17.07.2014
comment
Итак, я получил это, используя imp2.setRoi(roi1). Я не использую beanshell-код, поэтому я его не понял. Я пробовал оверлей, но он не работает на моем. Также вы можете сделать это для двух или более изображений? - person New Programmer; 17.07.2014
comment
Вы можете добавить несколько Roi к Overlay, используя Overlay#add(ij.gui.Roi), но ImagePlus (сам по себе лишенный прозрачности) может иметь только один текущий выбор, возвращаемый ImagePlus#getRoi(). - person Jan Eglinger; 17.07.2014