首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

吞食鱼游戏蒙版图步骤把鱼放到背景中

2012-11-22 
吞食鱼游戏蒙版图方法把鱼放到背景中最近在移动硬盘的角落中发现大学时代玩过的一个吞食鱼游戏,相信很多人

吞食鱼游戏蒙版图方法把鱼放到背景中

最近在移动硬盘的角落中发现大学时代玩过的一个吞食鱼游戏,相信很多人都玩过。随意点进去之后,发现游戏程序的图片库中,有鱼图片和黑白的鱼模型图片

吞食鱼游戏蒙版图步骤把鱼放到背景中

让我很是不解,于是baidu了一下,原来是蒙版图抠图的一种方法,索性就自己写了个程序试了试,还真管用,下面把我理解的原理和写的测试程序发出来共享学习。

如果用蒙版图方式把一条鱼从图片中抠出来,再合成到背景图片中,大概有如下几个步骤:

1、准备蒙版图,如下的黑白鱼图片,当然也可以是白黑图。此图的特点是图片中的鱼模型和需要抠的鱼形状一致。

吞食鱼游戏蒙版图步骤把鱼放到背景中

2、把黑白图片数据取反,得到白黑图(图片像素数据位中,0是黑色1是白色,取反之后黑白对换)。

3、把白黑图与背景图做与,即白黑图&背景图(注意:1&color=color,0&color=0)得到的图片是中间一个黑色鱼模型,周围是背景图片

吞食鱼游戏蒙版图步骤把鱼放到背景中

4、把黑白图(注意与白黑图的区别)与鱼的原始图片做与,即黑白图 &鱼图片,得到的是图片中间一条鱼,周围是黑色。一般为加快处理速度,这种图片可以提前生成。

吞食鱼游戏蒙版图步骤把鱼放到背景中

5、把上面的有黑色鱼模型的背景图,周围是黑色的鱼图片,做或运算(注意:1 | color = 1,0 | color = color),这样得到的图片就是鱼加到背景图片中。

吞食鱼游戏蒙版图步骤把鱼放到背景中

其实挺简单的,不过现在游戏平台都支持透明像素和图层,应该很少用这种合成方式了吧,这方面我还是不很了解。

下面是我写的测试程序,用到的图片我上传到csdn资源中,不需要积分:

import java.awt.Component;import java.awt.Graphics;import java.awt.Image;import java.awt.MediaTracker;import java.awt.Point;import java.awt.image.MemoryImageSource;import java.awt.image.PixelGrabber;import java.io.File;import java.util.Arrays;import javax.imageio.ImageIO;import javax.swing.Icon;import javax.swing.JFrame;import javax.swing.JLabel;public class Testimg extends JFrame{/** * @param args */public static void main(String[] args) {Testimg t = new Testimg();}//6张黑白图private Image[] maskImage = new Image[6];//6张鱼图片private Image[] sourceImage = new Image[6];//背景图片private Image bgImage;private MediaTracker tracker;private PixelGrabber[] maskPg = new PixelGrabber[6];private PixelGrabber[] sourcePg = new PixelGrabber[6];private PixelGrabber bgPg;public Testimg(){try {tracker = new MediaTracker( this );//加载黑白图和鱼图片for (int i=1;i<=6;i++){sourceImage[i-1] = ImageIO.read(new File("D:/images/eat_cycle."+i+".jpg"));maskImage[i-1] = ImageIO.read(new File("D:/images/_eat_cycle."+i+".png"));tracker.addImage(sourceImage[i-1], 0);tracker.addImage(maskImage[i-1], 0);}//加载背景图片bgImage = ImageIO.read(new File("D:/images/mainbg.jpg"));tracker.addImage(bgImage, 0);tracker.waitForAll();int mw = maskImage[0].getWidth( this );int mh = maskImage[0].getHeight( this );int[][] mPixs = new int[6][ mw * mh ];int sw = sourceImage[0].getWidth( this );int sh = sourceImage[0].getHeight( this );int[][] sPixs = new int[6][ sw * sh ];int bw = bgImage.getWidth(this);int bh = bgImage.getHeight(this);int[] bPixs = new int[ bw * bh ]; //背景图片像素int[] _bPixs = new int[ bw * bh ]; //临时背景图片像素for (int i=0;i<6;i++){maskPg[i] = new PixelGrabber( maskImage[i], 0, 0, mw, mh, mPixs[i], 0, mw );sourcePg[i] = new PixelGrabber( sourceImage[i], 0, 0, sw, sh, sPixs[i], 0, sw );maskPg[i].grabPixels();sourcePg[i].grabPixels();}bgPg = new PixelGrabber( bgImage, 0, 0, bw, bh, bPixs, 0, bw );bgPg.grabPixels();Point p = new Point(200,240); //鱼图片在背景图片中的初始坐标JLabel label = new JLabel();setSize(bw,bh);add(label);setVisible(true);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//下面的while循环开始把鱼放到背景中while(true){for (int t=0;t<6;t++){Thread.sleep(300);//每次鱼图片的初始x坐标减少10像素,感觉鱼在游动p.setLocation(p.x-10, p.y);//把原始背景图片像素复制到临时数组中//相当于重置背景图片的作用_bPixs = Arrays.copyOf(bPixs, bPixs.length);for (int i=0;i<mPixs[0].length;i++){//把鱼图片数据赋值到临时背景图片数据中//这里写的赋值语句一步到位,具体含义是这样的//1、~mPixs[t][i]这是把黑白图取反,得到的是白黑图。就是图片中间是一条黑色鱼,周围是白色。//2、(i/mw+p.y)*bw+(i%mw+p.x)这个是换算公式,根据白黑图的像素坐标i换算成背景图中以p.x p.y起始的相对位置坐标。//3、~mPixs[t][i] & _bPixs[(i/mw+p.y)*bw+(i%mw+p.x)]白黑图与背景图做&运算,得到的图片中间是黑色的鱼图形,周围是背景的图片。//4、| sPixs[t][i]最后一步与原始鱼图片做|运算,就把鱼加到背景中了。_bPixs[(i/mw+p.y)*bw+(i%mw+p.x)] = ~mPixs[t][i] & _bPixs[(i/mw+p.y)*bw+(i%mw+p.x)] | sPixs[t][i];}//用处理完的临时背景图片设置到labelbgImage = createImage( new MemoryImageSource( bw, bh, _bPixs, 0, bw) );label.setIcon(new Icon() {public void paintIcon(Component c, Graphics g, int x, int y) {g.drawImage( bgImage, 0, 0, null );}public int getIconWidth() {return bgImage.getWidth(null);}public int getIconHeight() {return bgImage.getHeight(null);}});}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}



热点排行