java抠图_java利用透明的图片轮廓抠图

importjava.awt.Graphics2D;importjava.awt.Image;importjava.awt.Rectangle;importjava.awt.Shape;importjava.awt.Transparency;importjava.awt.geom.Area;importjava.awt.image.BufferedImage;importjava.awt.image.PixelGrabber;importjava.io.File;importjava.io.IOException;importjava.util.ArrayList;importjavax.imageio.ImageIO;/***

* 利用透明的背景轮廓抠图

* 参考了:http://blog.csdn.net/daixinmei/article/details/51085575后实现

*

*@authoryzl

*@see[相关类/方法](可选)

*@since[产品/模块版本] (可选)*/

public classTwoComposePic {/***

* 将Image图像中的透明/不透明部分转换为Shape图形

*

*@paramimg 图片信息

*@paramtransparent 是否透明

*@return*@throwsInterruptedException

*@see[相关类/方法](可选)

*@since[产品/模块版本](可选)*/

public static Shape getImageShape(Image img, boolean transparent) throwsInterruptedException {

ArrayList x = new ArrayList();

ArrayList y = new ArrayList();int width = img.getWidth(null);int height = img.getHeight(null);//首先获取图像所有的像素信息

PixelGrabber pgr = new PixelGrabber(img, 0, 0, -1, -1, true);

pgr.grabPixels();int pixels[] = (int[]) pgr.getPixels();//循环像素

for (int i = 0; i < pixels.length; i++) {//筛选,将不透明的像素的坐标加入到坐标ArrayList x和y中

int alpha = (pixels[i] >> 24) & 0xff;if (alpha == 0) {continue;

}else{

x.add(i% width > 0 ? i % width - 1 : 0);

y.add(i% width == 0 ? (i == 0 ? 0 : i / width - 1) : i /width);

}

}//建立图像矩阵并初始化(0为透明,1为不透明)

int[][] matrix = new int[height][width];for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {

matrix[i][j]= 0;

}

}//导入坐标ArrayList中的不透明坐标信息

for (int c = 0; c < x.size(); c++) {

matrix[y.get(c)][x.get(c)]= 1;

}/** 逐一水平"扫描"图像矩阵的每一行,将透明(这里也可以取不透明的)的像素生成为Rectangle,

* 再将每一行的Rectangle通过Area类的rec对象进行合并, 最后形成一个完整的Shape图形*/Area rec= newArea();int temp = 0;//生成Shape时是1取透明区域还是取非透明区域的flag

int flag = transparent ? 0 : 1;for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {if (matrix[i][j] ==flag) {if (temp == 0)

temp=j;else if (j ==width) {if (temp == 0) {

Rectangle rectemp= new Rectangle(j, i, 1, 1);

rec.add(newArea(rectemp));

}else{

Rectangle rectemp= new Rectangle(temp, i, j - temp, 1);

rec.add(newArea(rectemp));

temp= 0;

}

}

}else{if (temp != 0) {

Rectangle rectemp= new Rectangle(temp, i, j - temp, 1);

rec.add(newArea(rectemp));

temp= 0;

}

}

}

temp= 0;

}returnrec;

}/***

* 功能描述:

* 〈功能详细描述〉

*

*@paramback

*@paramhead

*@paramout

*@see[相关类/方法](可选)

*@since[产品/模块版本](可选)*/

public voidcomposePic(String back, String head, String out) {try{//带人物轮廓的背景图(人物轮廓透明)

File backFile = newFile(back);

Image backImg=ImageIO.read(backFile);int bw = backImg.getWidth(null);int bh = backImg.getHeight(null);//人物的head图

File headFile = newFile(head);

Image headImg=ImageIO.read(headFile);int lw = headImg.getWidth(null);int lh = headImg.getHeight(null);//得到透明的区域(人物轮廓)

Shape shape = getImageShape(ImageIO.read(new File(back)), true);//合成后的图片

BufferedImage img = newBufferedImage(bw, bh, BufferedImage.TYPE_INT_RGB);

Graphics2D g2d=img.createGraphics();//设置画布为透明

img =g2d.getDeviceConfiguration().createCompatibleImage(bw, bh, Transparency.TRANSLUCENT);

g2d.dispose();

g2d=img.createGraphics();//取交集(限制可以画的范围为shape的范围)

g2d.clip(shape);//这里的坐标需要根据实际情况进行调整

g2d.drawImage(headImg, 98, 10, lw, lh, null);

g2d.dispose();

ImageIO.write(img,"png", newFile(out));

}catch(Exception e) {

e.printStackTrace();

}

}public static void main(String args[]) throwsIOException {

String basePath= "E:/test/";

TwoComposePic pic= newTwoComposePic();

pic.composePic(basePath+"1.png", basePath+"2.png", basePath+"result.png");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值