现在的位置: 首页 > 综合 > 正文

java 图像处理——抠图

2018年01月30日 ⁄ 综合 ⁄ 共 3719字 ⁄ 字号 评论关闭

 

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

抱歉!评论已关闭.