java抠图_java 图像处理——抠图 | 学步园

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Image;

import java.awt.MediaTracker;

import java.awt.image.BufferedImage;

import java.awt.image.MemoryImageSource;

import java.awt.image.PixelGrabber;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.LineBorder;

public class CropImage extends JFrame

{

private static final long serialVersionUID = -2656049481667364613L;

public static void main( String[] args )

{

CropImage test = new CropImage();

test.setVisible( true );

}

private MediaTracker tracker;

private PixelGrabber maskPg;

private PixelGrabber sourcePg;

private Image backgroundImage;

private Image maskImage;//蒙版图片

private Image sourceImage;//源图片

private Image resultImage;

private BackgroundPanel backPanel;

private RocketPanel rocketPanel;

public CropImage()

{

super();

setBounds( 100, 100, 500, 500 );

setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

loadImage();

setResultImage( sourceImage, maskImage );

backPanel = new BackgroundPanel();

backPanel.setLayout( null );

rocketPanel = new RocketPanel();

rocketPanel.setBorder( new LineBorder( Color.WHITE ) );

setContentPane( backPanel );

rocketPanel.setBounds( 200, 200, 42, 42 );

backPanel.add( rocketPanel );

}

/**

* 加载图片

*/

public void loadImage()

{

tracker = new MediaTracker( this );

try

{

backgroundImage = ImageIO.read( new File( "d:/3.jpg" ) );

tracker.addImage( backgroundImage, 0 );

maskImage = ImageIO.read( new File( "d:/1.gif" ) );

tracker.addImage( maskImage, 1 );

sourceImage = ImageIO.read( new File( "d:/2.gif" ) );

tracker.addImage( sourceImage, 1 );

}

catch (IOException e)

{

e.printStackTrace();

}

try

{

tracker.waitForID( 0 );

tracker.waitForID( 1 );

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

/**

* 获取新图片

* @param source

* @param mask

*/

public void setResultImage( Image source, Image mask )

{

int mw = mask.getWidth( this );

int mh = mask.getHeight( this );

int[] mPixs = new int[ mw * mh ];//蒙版图片像素

int sw = source.getWidth( this );

int sh = source.getHeight( this );

int[] sPixs = new int[ sw * sh ];//源图片像素

maskPg = new PixelGrabber( mask, 0, 0, mw, mh, mPixs, 0, mw );

sourcePg = new PixelGrabber( source, 0, 0, sw, sh, sPixs, 0, sw );

try

{

//获取像素

maskPg.grabPixels();

sourcePg.grabPixels();

}

catch (InterruptedException e)

{

System.err.println("interrupted waiting for pixels!");

return;

}

//结果图片的像素

int[] rPixels = new int[ sw * sh ];

for ( int i = 0; i < rPixels.length; i++ )

{

//将源图片的像素赋给结果图片的像素

rPixels[i] = sPixs[i];

int mPixelRgb = mPixs[i] & 0x00ffffff;

//判断背景像素的rgb是否小于0x00808080

if ( mPixelRgb < 0x00808080 )

{

//背景透明处理

rPixels[i] = rPixels[i] & 0x00ffffff;

}

}

//生成结果图片

resultImage = createImage( new MemoryImageSource( sw, sh, rPixels, 0, sw) );

BufferedImage rImage = new BufferedImage( 100, 100, BufferedImage.TYPE_4BYTE_ABGR );

Graphics g = rImage.getGraphics();

g.drawImage( resultImage, 0, 0, null );

try

{

//保存图片

ImageIO.write( rImage, "png", new File( "d:/jewel.png" ) );

}

catch (IOException e)

{

e.printStackTrace();

}

}

private class BackgroundPanel extends JPanel

{

private static final long serialVersionUID = 4503016479516384644L;

@Override

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

if ( backgroundImage != null )

{

int w = BackgroundPanel.this.getWidth();

int h = BackgroundPanel.this.getHeight();

g.drawImage( backgroundImage, 0, 0, w, h, null );

}

}

}

private class RocketPanel extends JPanel

{

private static final long serialVersionUID = 1204792957097831219L;

public RocketPanel()

{

super();

setOpaque( false );

}

@Override

protected void paintComponent(Graphics g)

{

super.paintComponent(g);

if ( resultImage != null )

{

int w = RocketPanel.this.getWidth();

int h = RocketPanel.this.getHeight();

g.drawImage( resultImage, 0, 0, w, h, null );

}

}

}

}

除非必要否则不要去透明,游戏需要大量的贴图,这种操作速度会差很多。一般来说你是把一个图贴到另一个图上。蒙版图还要个白黑图(你的是黑白图,只要运算时将蒙版图的每像素的每位做个取反操作)。

这样把钻石贴到背景图的步骤是

1、将背景图与(&)蒙版图( 白黑图 ),这样得到的是背景图上有个黑色的钻石。(蒙版图最好给个白黑图,这样可以省去取反操作)

2、把蒙版图(白黑图)或(|)钻石图,这样得到一个钻石图,边上是黑色色。(为加快速度,这个图片是可以事先生成的,这样这一步就可以省略)

3、把第一步得到的图或(|)第二步得到的图,这样就将钻石贴到了背景图上。

当然蒙版图是黑白图,那么第二步就应该给钻石图,边上是白色,这样第三步就是做与(&)操作了。

贴图原理很简单

黑色每bit都是0,白色是1

0 & color = 0

0 | color = color

1 & color = color

1 | color = 1

你可能感兴趣的:(java抠图)