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