关于ALPHACOMPOSITE的理解——图片合成,透明度处理

转载自http://www.cnitblog.com/zcy860511/archive/2009/01/25/54017.html

我将对java 2D进行一些讲述,当然是原创,不过也是参考自sun公司自己编写的java tutorial。
下面是这个指南的地址,以及一些来自官方的翻译版本

关于Composite的官方版本(英文) 
AlphaComposite,是关于两个目标重叠的混合处理类,该类提供了一个getInstance的方法,其中的两个参数为rule和alpha,第二个参数将由调用者设置一个alpha值,即是透明度的设置,而第一个参数则是混合方式,也可以翻译为一种规则,并分为以下几种方式

SRC
SRC_IN
SRC_OUT
SRC_OVER
按照为都认识,所谓源模式,也就是将源(Source,以下简称src)放在上面,目标放在下面(Destination,以下简称dst),in便是忽略掉src再dst的外面部分,out则是忽略掉里面部分,over则是覆盖在dst的上面
DST_IN
DST_OUT
DST_OVER
所谓目标模式,就是与源模式相反,将源模式放在下面,将目标模式放在上面,in便是忽略掉dst都与源的飞重叠部分,而out便是忽略掉dst的重叠部分,over自然是将dst覆盖在上面
CLEAR
顾名思义,就是清楚掉一部分。。。但是清楚的确实源部分,这个需要记忆一下
下面是sun提供的演示
 



这个是sun自己写的演示,所以比较具有权威性,我看过代码来,完全使用对象方式绘制,而问题就在于使用Graphics中的非对象方法时不能实现覆盖。

 

package com.ciash.test;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

import javax.swing.JApplet;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class Composite extends JApplet implements ItemListener {
    /**
     * 字段描述:
     */
    private static final long serialVersionUID = 1741029974281299482L;
    CompPanel comp;
    JLabel alphaLabel, rulesLabel;
    JComboBox alphas, rules;
    String alpha = "1.0";
    int rule = 0;

    // Initializes the layout of the components.
    public void init() {
        GridBagLayout layOut = new GridBagLayout();
        getContentPane().setLayout(layOut);

        GridBagConstraints l = new GridBagConstraints();
        l.weightx = 1.0;
        l.fill = GridBagConstraints.BOTH;
        l.gridwidth = GridBagConstraints.RELATIVE;
        alphaLabel = new JLabel();
        alphaLabel.setText("Alphas");
        Font newFont = getFont().deriveFont(1);
        alphaLabel.setFont(newFont);
        alphaLabel.setHorizontalAlignment(JLabel.CENTER);
        layOut.setConstraints(alphaLabel, l);
        getContentPane().add(alphaLabel);   
        GridBagConstraints c = new GridBagConstraints();
        getContentPane().setLayout(layOut);

        l.gridwidth = GridBagConstraints.REMAINDER;
        rulesLabel = new JLabel();
        rulesLabel.setText("Rules");
        newFont = getFont().deriveFont(1);
        rulesLabel.setFont(newFont);
        rulesLabel.setHorizontalAlignment(JLabel.CENTER);
        layOut.setConstraints(rulesLabel, l);
        getContentPane().add(rulesLabel);   

        GridBagConstraints a = new GridBagConstraints();
        a.gridwidth = GridBagConstraints.RELATIVE;
        a.weightx = 1.0;
        a.fill = GridBagConstraints.BOTH;
        alphas = new JComboBox();
        layOut.setConstraints(alphas, a);
        alphas.addItem("1.0");
        alphas.addItem("0.75");
        alphas.addItem("0.50");
        alphas.addItem("0.25");
        alphas.addItem("0.0");
        alphas.addItemListener(this);
        getContentPane().add(alphas);

        a.gridwidth = GridBagConstraints.REMAINDER;
        rules = new JComboBox();
        layOut.setConstraints(rules, a);
        rules.addItem("SRC");
        rules.addItem("DST_IN");
        rules.addItem("DST_OUT");
        rules.addItem("DST_OVER");
        rules.addItem("SRC_IN");
        rules.addItem("SRC_OVER");
        rules.addItem("SRC_OUT");
        rules.addItem("CLEAR");
        rules.addItemListener(this);
        getContentPane().add(rules);

        GridBagConstraints fC = new GridBagConstraints(); 
        fC.fill = GridBagConstraints.BOTH;
        fC.weightx = 1.0;
        fC.weighty = 1.0;
        fC.gridwidth = GridBagConstraints.REMAINDER;
        comp = new CompPanel();
        layOut.setConstraints(comp, fC);
        getContentPane().add(comp); 

        validate();
    }

/*
 * Detects a change in either of the Choice components.  Resets the variable corresponding
 * to the Choice whose state is changed.  Invokes changeRule in CompPanel with the current
 * alpha and composite rules.
*/
    public void itemStateChanged(ItemEvent e){
        if ( e.getStateChange() != ItemEvent.SELECTED ) {
            return;
        }

        Object choice = e.getSource();
        if ( choice == alphas ) {
            alpha = (String)alphas.getSelectedItem();
        } else {
            rule = rules.getSelectedIndex();
        }
        comp.changeRule(alpha, rule);
    }

    public static void main(String s[]) {
        JFrame f = new JFrame("Composite");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {System.exit(0);}
        });
        JApplet applet = new Composite();
        f.getContentPane().add("Center", applet);
        applet.init();
        f.pack();
        f.setSize(new Dimension(300,300));
        f.setVisible(true);
    }
}


class CompPanel extends JPanel {

    AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC);  
    float alpha = 1.0f;

    public CompPanel(){}

// Resets the alpha and composite rules with selected items.    
    public void changeRule(String a, int rule) {
        alpha = Float.valueOf(a).floatValue();
        ac = AlphaComposite.getInstance(getRule(rule), alpha);
        repaint();
    }

// Gets the requested compositing rule.
    public int getRule(int rule){
        int alphaComp = 0;
        switch ( rule ) {
        case 0: alphaComp = AlphaComposite.SRC; break;
        case 1: alphaComp = AlphaComposite.DST_IN; break;
        case 2: alphaComp = AlphaComposite.DST_OUT; break;
        case 3: alphaComp = AlphaComposite.DST_OVER; break;
        case 4: alphaComp = AlphaComposite.SRC_IN; break;
        case 5: alphaComp = AlphaComposite.SRC_OVER; break;
        case 6: alphaComp = AlphaComposite.SRC_OUT; break;
        case 7: alphaComp = AlphaComposite.CLEAR; break;
        }
        return alphaComp;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent( g );
        Graphics2D g2 = (Graphics2D) g;

        Dimension d = getSize();
        int w = d.width;
        int h = d.height; 

        // Creates the buffered image.
        BufferedImage buffImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        Graphics2D gbi = buffImg.createGraphics();

        // Clears the previously drawn image.
        g2.setColor(Color.white);
        g2.fillRect(0, 0, d.width, d.height);

        int rectx = w/4;
        int recty = h/4;

        // Draws the rectangle and ellipse into the buffered image.
        gbi.setColor(new Color(0.0f, 0.0f, 1.0f, 1.0f));
        gbi.fill(new Rectangle2D.Double(rectx, recty, 150, 100));
        gbi.setColor(new Color(1.0f, 0.0f, 0.0f, 1.0f));    
        gbi.setComposite(ac);
        gbi.fill(new Ellipse2D.Double(rectx+rectx/2,recty+recty/2,150,100));

        // Draws the buffered image.
        g2.drawImage(buffImg, null, 0, 0);
    }
}   

下面是实用方法

/**
     * 图二的位置 从左上角开始
     * @param x
     * @param y
     */
    public static void createPicTwo(int x,int y)
    {
        try
        {
            //读取第一张图片
            File fileOne = new File("c:\\1.gif");
            BufferedImage ImageOne = ImageIO.read(fileOne);
            int width = ImageOne.getWidth();//图片宽度
            int height = ImageOne.getHeight();//图片高度
            //从图片中读取RGB
            int[] ImageArrayOne = new int[width*height];
            ImageArrayOne = ImageOne.getRGB(0,0,width,height,ImageArrayOne,0,width);
            //对第二张图片做相同的处理
            File fileTwo = new File("c:\\2.gif");
            BufferedImage ImageTwo = ImageIO.read(fileTwo);
            int widthTwo = ImageTwo.getWidth();//图片宽度
            int heightTwo = ImageTwo.getHeight();//图片高度
            int[] ImageArrayTwo = new int[widthTwo*heightTwo];
            ImageArrayTwo = 
                ImageTwo.getRGB(0,0,widthTwo,heightTwo,ImageArrayTwo,0,widthTwo);

            //生成新图片
            BufferedImage ImageNew = new         
            BufferedImage(width*2,height,BufferedImage.TYPE_INT_RGB);
            ImageNew.setRGB(0,0,width,height,ImageArrayOne,0,width);//设置左半部分的RGB
            ImageNew.setRGB(x,y,widthTwo,heightTwo,ImageArrayTwo,0,widthTwo);//设置右半部分的RGB
            File outFile = new File("c:\\out.png");
            ImageIO.write(ImageNew, "png", outFile);//写图片

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }


    /**
     *  解决透明的问题
     * @param filesrc
     * @param logosrc
     * @param outsrc
     * @param x 位置
     * @param y 位置
     */
    public static void composePic(String filesrc,String logosrc,String outsrc,int x,int y) {
        try {
            File bgfile = new File(filesrc);
            Image bg_src = javax.imageio.ImageIO.read(bgfile);

            File logofile = new File(logosrc);
            Image logo_src = javax.imageio.ImageIO.read(logofile);

            int bg_width = bg_src.getWidth(null);
            int bg_height = bg_src.getHeight(null);
            int logo_width = logo_src.getWidth(null);;
            int logo_height = logo_src.getHeight(null);

            BufferedImage tag = new BufferedImage(bg_width, bg_height, BufferedImage.TYPE_INT_RGB);

            Graphics2D g2d = tag.createGraphics();
            g2d.drawImage(bg_src, 0, 0, bg_width, bg_height, null);

            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,1.0f)); //透明度设置开始
            g2d.drawImage(logo_src,x,y,logo_width,logo_height, null);
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); //透明度设置 结束

            FileOutputStream out = new FileOutputStream(outsrc);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(tag);
            out.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

调用main方法合成

   public static void main(String[] args) { 
            Long star = System.currentTimeMillis();
            composePic("E:\\a\\bb.png","E:\\a\\bc.png","E:\\a\\out_pic.png",59,218);
            Long end =System.currentTimeMillis();
            System.out.print("time====:"+(end-star));
   }

 

你可能感兴趣的:(#,Java,图片合成)