达夫设备 java_波特-达夫规则!

本文介绍了1984年Porter和Duff提出的合成数字图像的12条规则,这些规则在Java 1.2版的AlphaComposite类中得到实现。通过示例解释了每条规则如何影响图像的合成,特别是对于游戏开发中的图像叠加和透明度处理。读者可以通过一个交互式的Java程序体验不同规则的效果。
摘要由CSDN通过智能技术生成

早在1984年,托马斯·波特(Thomas Porter)和汤姆·达夫(Tom Duff)撰写了一篇题为“合成数字图像”的论文,该论文描述了结合两个图像的12条规则。 在Java语言的1.2版中首次引入的AlphaComposite类中找到了对这些合成规则的支持。 当前处于beta 2中的1.4版支持所有12条规则。

对于诸如游戏之类的应用程序,包括多种图像类型(包括背景图像,玩家角色图像等)的应用程序,必须支持合成。 虽然很容易总是将玩家吸引到背景的前面,但是如果玩家跳到一棵树后面,您可能希望显示角色图像在树图像后面逐渐消失。 这是合成方便的地方。

波特和达夫的12条规则

AlphaComposite类具有12个常量,每个规则一个。 可视化规则的应用方式可能很棘手,因此我提供了每个操作规则的说明。 如果图像不是不透明的,则实际组合会有所不同。 该示范项目,在所示清单1和可供下载的相关主题部分,让你尝试不同级别的透明度。

注意:Merlin版本中新添加的那些规则以星号(*)表示。

规则1. AlphaComposite.CLEAR :在合成图像中不会绘制任何内容。

AlphaComposite.CLEAR
AlphaComposite.CLEAR

规则2. AlphaComposite.SRC :SRC代表源; 只有源图像将在组合图像中。

阿尔法复合材料
阿尔法复合材料

规则3. AlphaComposite.DST *:DST代表目的地; 只有目标图像将在组合图像中。

AlphaComposite DST
AlphaComposite DST

规则4. AlphaComposite.SRC_OVER :源图像将绘制在目标图像上。

AlphaComposite.SRC_OVER
AlphaComposite.SRC_OVER

规则5. AlphaComposite.DST_OVER :目标图像将绘制在源图像上。

AlphaComposite.DST_OVER
AlphaComposite.DST_OVER

规则6. AlphaComposite.SRC_IN :仅绘制源图像中与目标图像重叠的部分。

AlphaComposite.SRC_IN
AlphaComposite.SRC_IN

规则7. AlphaComposite.DST_IN :仅绘制目标图像中与源图像重叠的部分。

AlphaComposite.DST_IN
AlphaComposite.DST_IN

规则8. AlphaComposite.SRC_OUT :仅绘制源图像中与目标图像不重叠的部分。

AlphaComposite.SRC_OUT
AlphaComposite.SRC_OUT

规则9. AlphaComposite.DST_OUT :仅绘制目标图像中与源图像不重叠的部分。

AlphaComposite.DST_OUT
AlphaComposite.DstOut

规则10. AlphaComposite.SRC_ATOP *:将绘制源图像中与目标图像重叠的部分以及目标图像中与源图像不重叠的部分。

AlphaComposite.SRC_ATOP
AlphaComposite.SRC_ATOP

规则11. AlphaComposite.DST_ATOP *:将绘制目标图像中与源图像重叠的部分,以及源图像中与目标图像不重叠的部分。

AlphaComposite.DST_ATOP
AlphaComposite.DST_ATOP

规则12. AlphaComposite.XOR *:源图像中与目标图像不重叠的部分将与目标图像中与源图像不重叠的部分一起绘制。

AlphaComposite.XOR
AlphaComposite.XOR

一个完整的例子

以下程序是alpha合成规则的交互式演示。 只需更改每个三角形的不透明度,然后选择一个规则即可使用以查看混合图像的效果。

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.lang.reflect.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;

public class CompositeIt extends JFrame {
  JSlider sourcePercentage = new JSlider();
  JSlider destinationPercentage = new JSlider();
  JComboBox alphaComposites = new JComboBox();
  DrawingPanel drawingPanel = new DrawingPanel();

  public CompositeIt() {
    super("Porter-Duff");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel contentPane = (JPanel) this.getContentPane();
    Dictionary labels = new Hashtable();
    labels.put(new Integer(0),   new JLabel("0.0"));
    labels.put(new Integer(25),  new JLabel("0.25"));
    labels.put(new Integer(33),  new JLabel("0.33"));
    labels.put(new Integer(50),  new JLabel("0.50"));
    labels.put(new Integer(67),  new JLabel("0.67"));
    labels.put(new Integer(75),  new JLabel("0.75"));
    labels.put(new Integer(100), new JLabel("1.00"));
    sourcePercentage.setOrientation(JSlider.VERTICAL);
    sourcePercentage.setLabelTable(labels);
    sourcePercentage.setPaintTicks(true);
    sourcePercentage.setPaintLabels(true);
    sourcePercentage.setValue(100);
    sourcePercentage.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        int sourceValue = sourcePercentage.getValue();
        drawingPanel.setSourcePercentage(sourceValue/100.0f);
      }
    });
    destinationPercentage.setOrientation(JSlider.VERTICAL);
    destinationPercentage.setLabelTable(labels);
    destinationPercentage.setPaintTicks(true);
    destinationPercentage.setPaintLabels(true);
    destinationPercentage.setValue(100);
    destinationPercentage.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent e) {
        int destinationValue = destinationPercentage.getValue();
        drawingPanel.setDestinationPercentage(destinationValue/100.0f);
      }
    });
    String rules[] = {
      "CLEAR",    "DST", 
      "DST_ATOP", "DST_IN", 
      "DST_OUT",  "DST_OVER", 
      "SRC",      "SRC_ATOP", 
      "SRC_IN",   "SRC_OUT", 
      "SRC_OVER", "XOR"};
    ComboBoxModel model = new DefaultComboBoxModel(rules);
    alphaComposites.setModel(model);
    alphaComposites.setSelectedItem("XOR");
    alphaComposites.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String alphaValue = alphaComposites.getSelectedItem().toString();
        Class alphaClass = AlphaComposite.class;
        try {
          Field field = alphaClass.getDeclaredField(alphaValue);
          int rule = ((Integer)field.get(AlphaComposite.Clear)).intValue();
          drawingPanel.setCompositeRule(rule);
        } catch (Exception exception) {
          System.err.println("Unable to find field");
        }
      }
    });
    contentPane.add(sourcePercentage, BorderLayout.WEST);
    contentPane.add(destinationPercentage, BorderLayout.EAST);
    contentPane.add(alphaComposites, BorderLayout.SOUTH);
    contentPane.add(drawingPanel, BorderLayout.CENTER);
    pack();
  }

  public static void main(String args[]) {
    new CompositeIt().show();
  }

  class DrawingPanel extends JPanel {
    GeneralPath sourcePath, destPath;
    BufferedImage source, dest;
    float sourcePercentage = 1, destinationPercentage = 1;
    int compositeRule = AlphaComposite.XOR;
    Dimension dimension = new Dimension(200, 200);

    public DrawingPanel() {
      sourcePath = new GeneralPath();  
      sourcePath.moveTo(0,   0);   sourcePath.lineTo(150, 0);
      sourcePath.lineTo(0, 200);   sourcePath.closePath();
      source = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
      destPath = new GeneralPath();
      destPath.moveTo(200,  0);    destPath.lineTo(50, 0);
      destPath.lineTo(200, 200);    destPath.closePath();
      dest = new BufferedImage(200, 200, BufferedImage.TYPE_INT_ARGB);
    }

    public void setSourcePercentage(float value) {
      sourcePercentage = value;
       repaint();
    }

    public void setDestinationPercentage(float value) {
      destinationPercentage = value;
       repaint();
    }

    public void setCompositeRule(int value) {
      compositeRule = value;
       repaint();
    }

    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D)g;
      Graphics2D sourceG = source.createGraphics();
      Graphics2D destG = dest.createGraphics();

      destG.setComposite(AlphaComposite.Clear);
      destG.fillRect(0, 0, 200, 200);
      destG.setComposite(AlphaComposite.getInstance(
          AlphaComposite.XOR, destinationPercentage));
      destG.setPaint(Color.magenta);
      destG.fill(destPath);

      sourceG.setComposite(AlphaComposite.Clear);
      sourceG.fillRect(0, 0, 200, 200);
      sourceG.setComposite(AlphaComposite.getInstance(
        AlphaComposite.XOR, sourcePercentage));
      sourceG.setPaint(Color.green);
      sourceG.fill(sourcePath);

      destG.setComposite(AlphaComposite.getInstance(compositeRule));
      destG.drawImage(source, 0, 0, null);
      g2d.drawImage(dest, 0, 0, this);
    }

    public Dimension getPreferredSize() {
      return dimension;
    }
  }
}

翻译自: https://www.ibm.com/developerworks/java/library/j-mer0918/index.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现图片透明效果,从演示截图可看到,上层图片与下层图片互相重叠,也就是上层图片透明了,看到了下层以的图片,具体的代码实现:   public class HalfTransparentImageDemo extends JFrame {    private Container content = getContentPane(); //获得窗口的容器    private JSlider jSlider = new JSlider(JSlider.HORIZONTAL,0,100,75); //改变图像的透明度    DisplayPanel displayPanel = new DisplayPanel(); //显示图形面板    public HalfTransparentImageDemo() {    super("半透明图片"); //调用父类构造器    jSlider.setPaintTicks(true); //绘制标志位    jSlider.setMajorTickSpacing(25); //设置标志尺寸    jSlider.setMinorTickSpacing(5);    jSlider.setPaintLabels(true); //绘制出数字    jSlider.setBorder(new TitledBorder(BorderFactory.createEmptyBorder(), "图像的透明度(%)")); //设置边框    jSlider.addChangeListener(new ChangeListener() { //滑动条jSlider事件处理    public void stateChanged(ChangeEvent ce) {    float alpha =((float) ((JSlider) ce.getSource()).getValue()) / 100;    displayPanel.alpha = alpha; //改变图像的透明度    displayPanel.repaint(); //重绘displayPanel    }    g2d.drawImage(bufImage1, 0, 0, this); //在图形环境绘制缓冲区图像1    g2d.drawString("Destination",5,20); //绘制文字    int compositeRule = AlphaComposite.SRC_OVER; //源排斥目标法合成规则    AlphaComposite alphaComposite=AlphaComposite.getInstance(compositeRule,alpha); //创建AlphaComposite对象    g2d.setComposite(alphaComposite); //设置图形环境的合成方式    g2d.drawImage(bufImage2, 0, 0, this); //在图形环境绘制缓冲区图像2    g2d.drawString("Source",150,20); //绘制文字    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值