Java中的色度键效果

时间:2011-12-14 10:28:48

标签: java image-processing

我还需要找到一个允许在Java中实现“色度键”效果的库。该视频包含一些绿色部分,在渲染过程中替换为图片以创建新视频。

我正在将我的问题与一个类似的问题联系起来,这个问题已经得到回答,但回答不完整(Looking for Chromakey library in Java)。你能否详细说明你是如何做到的?几个月来我一直没有成功地反对同一个问题。

c00kiemon5ter指出了几个资源:

  • JavaCV
  • JAI(Java高级成像API)
  • Java Image Processing Cookbook

哪一个对你有用?

2 个答案:

答案 0 :(得分:0)

JavaCV包含许多处理视频流的方法。

这段代码可以帮助您入门:http://tech.groups.yahoo.com/group/OpenCV/message/59118但它在Java中可能太慢了。试试这种方法:

创建一个过滤器,将所有绿色像素转换为蒙版(查找“按颜色选择”的内容)。

使用遮罩将背景图像复制到视频中。

答案 1 :(得分:0)

我想用一段代码做出贡献,这给了我很好的结果。我想知道我是否使用了Aaron Digulla建议的类和方法。

请注意,在这种情况下,我的视频有黑色背景,这就是我用背景图片替换黑色的原因。当我可以编辑视频以获得绿色背景时,我希望获得更好的效果,因为黑色更有可能在视频主角中使用,并且替换错误的像素会导致非常糟糕的效果。

-

package transparentvideo;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import java.io.File;
import javax.media.Manager;
import javax.media.Player;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class TransparentVideo
{
Player mediaPlayer;

JFrame invisibleFrame;
JFrame visibleFrame;
JLabel videoScreen;
JPanel offScreenVideo;

String backgroundImageFile="nature.jpg";

String videoFile="girl.mov";

public TransparentVideo() 
{

    invisibleFrame = new JFrame();

    invisibleFrame.setSize(400, 400);

    Container container=invisibleFrame.getContentPane();
    offScreenVideo =  getvidComp();
    offScreenVideo.setPreferredSize(container.getSize());
    offScreenVideo.setVisible(true);

    container.add(offScreenVideo);
    invisibleFrame.setVisible(true);

    visibleFrame=new JFrame();
    visibleFrame.setSize(container.getSize());
    visibleFrame.setLocationRelativeTo(null);

    videoScreen = new JLabel();

    visibleFrame.getContentPane().add(videoScreen);

    visibleFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    visibleFrame.setVisible(true);

    invisibleFrame.setVisible(false);

    try 
    {
        while(true)
        {

            if(mediaPlayer.getState()==Player.Started)
                reDraw();
            Thread.sleep(100);
        }
    } 
    catch (Exception ex)
    {
        System.out.println(ex.getMessage());
    }
}


public void reDraw()
{
      BufferedImage bi=new BufferedImage(videoScreen.getWidth(), videoScreen.getHeight(),
              BufferedImage.TYPE_INT_ARGB);

      bi.getGraphics().drawImage(new ImageIcon(backgroundImageFile).getImage(), 0 , 0 ,
              videoScreen.getWidth(), videoScreen.getHeight(), null);

      BufferedImage screenShot = createImage((JComponent) offScreenVideo, 
              new Rectangle(invisibleFrame.getBounds()));
      Image im = makeColorTransparent(new ImageIcon(screenShot).getImage(), Color.BLACK);

      bi.getGraphics().drawImage(im, 0 ,0 , videoScreen.getWidth(), videoScreen.getHeight(), null);

      videoScreen.setIcon(new ImageIcon(bi));

}



public static BufferedImage createImage(Component component, Rectangle region) 
{

    if (!component.isDisplayable()) {
        Dimension d = component.getSize();

        if (d.width == 0 || d.height == 0) {
            d = component.getPreferredSize();
            component.setSize(d);
        }

        layoutComponent(component);
    }

    BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = image.createGraphics();

    if (!component.isOpaque()) 
    {
        g2d.setColor(component.getBackground());
        g2d.fillRect(region.x, region.y, region.width, region.height);
    }

    g2d.translate(-region.x, -region.y);
    component.paint(g2d);
    g2d.dispose();
    return image;
}


public static void layoutComponent(Component component) 
{
    synchronized (component.getTreeLock()) 
    {
        component.doLayout();

        if (component instanceof Container) 
        {
            for (Component child : ((Container) component).getComponents()) 
            {
                layoutComponent(child);
            }
        }
    }
}


public JPanel getvidComp()
{

         Manager.setHint(Manager.LIGHTWEIGHT_RENDERER,true);

         try
         {
            mediaPlayer = Manager.createRealizedPlayer(new File(videoFile).toURL());

            mediaPlayer.realize();

            mediaPlayer.prefetch();

            JPanel video=new JPanel(new BorderLayout());
            video.add(mediaPlayer.getVisualComponent()) ;

            mediaPlayer.start();

            return video;

         }

         catch( Exception d)
         {
             return null;

         }
}



public static Image makeColorTransparent( Image im, final Color color) 
{
    ImageFilter filter = new RGBImageFilter() 
    {
          public int markerRGB = color.getRGB() | 0xFF000000;


          public final int filterRGB(int x, int y, int rgb) 
          {
                Color c=new Color(rgb);

                int red=c.getRed();
                int green=c.getGreen();
                int blue=c.getBlue();

                //if(red<140 && green<140 && blue<140)
                {
                    int alpha=Math.max(Math.max(red , green), Math.max(green, blue))*3;
                    c=new Color(red , green , blue , alpha>255 ?255 :alpha );
                }

                return c.getRGB();
            }
      }; 

    ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
    return Toolkit.getDefaultToolkit().createImage(ip);
}


public static void main(String[] args) {
    new TransparentVideo();
}

}