需要处理的图片:

1.png(空白区域为透明)

2.png

处理后的结果图片:result.png

代码如下:

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import javax.imageio.ImageIO; /**
*
* 利用透明的背景轮廓抠图
* 参考了:http://blog.csdn.net/daixinmei/article/details/51085575后实现
*
* @author yzl
* @see [相关类/方法](可选)
* @since [产品/模块版本] (可选)
*/
public class TwoComposePic { /**
*
* 将Image图像中的透明/不透明部分转换为Shape图形
*
* @param img 图片信息
* @param transparent 是否透明
* @return
* @throws InterruptedException
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public static Shape getImageShape(Image img, boolean transparent) throws InterruptedException {
ArrayList<Integer> x = new ArrayList<Integer>();
ArrayList<Integer> y = new ArrayList<Integer>();
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 = new Area();
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(new Area(rectemp));
} else {
Rectangle rectemp = new Rectangle(temp, i, j - temp, 1);
rec.add(new Area(rectemp));
temp = 0;
}
}
} else {
if (temp != 0) {
Rectangle rectemp = new Rectangle(temp, i, j - temp, 1);
rec.add(new Area(rectemp));
temp = 0;
}
}
}
temp = 0;
}
return rec;
} /**
*
* 功能描述: <br>
* 〈功能详细描述〉
*
* @param back
* @param head
* @param out
* @see [相关类/方法](可选)
* @since [产品/模块版本](可选)
*/
public void composePic(String back, String head, String out) {
try {
//带人物轮廓的背景图(人物轮廓透明)
File backFile = new File(back);
Image backImg = ImageIO.read(backFile);
int bw = backImg.getWidth(null);
int bh = backImg.getHeight(null); //人物的head图
File headFile = new File(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 = new BufferedImage(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", new File(out));
} catch (Exception e) {
e.printStackTrace();
}
} public static void main(String args[]) throws IOException {
String basePath = "E:/test/";
TwoComposePic pic = new TwoComposePic();
pic.composePic(basePath+"1.png", basePath+"2.png", basePath+"result.png");
}
}

java利用透明的图片轮廓抠图的更多相关文章

  1. java利用直方图实现图片对比

    需求 实现两张图对比,找出其中不同的部分. 分析 首先将大图切片,分成许多小图片.然后进行逐个对比,并设定相似度阈值,判断是否是相同.最后整理,根据生成数组标记不同部分.如果切片足够小,便越能精确找出 ...

  2. java 生成透明背景图片

    //开始绘图 graphics2d.setBackground(Color.WHITE); graphics2d.clearRect(0, 0, width, height); graphics2d. ...

  3. Java利用poi生成word(包含插入图片,动态表格,行合并)

    转(小改): Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插 ...

  4. 利用box-shadow实现伪边框透明到图片

    前阵子突然看到了一个效果,一张图片,有一个边框,但是边框可以透明到图片.直接上图 贴代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr ...

  5. Java+jquery实现裁剪图片上传到服务器

    大体分两步: 1.利用jquery裁剪图片,把裁剪到的几个点传入后端 2.利用前端传入的几个点,来裁剪图片 首先,用到一个jquery的插件 imgAreaSelect 实例及插件下载地址:http: ...

  6. java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板

    java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring   本文主要介绍利用JavaMailS ...

  7. 谈谈Java利用原始HttpURLConnection发送POST数据

    这篇文章主要给大家介绍java利用原始httpUrlConnection发送post数据,设计到httpUrlConnection类的相关知识,感兴趣的朋友跟着小编一起学习吧 URLConnectio ...

  8. selenium+java利用AutoIT实现文件上传

    转自https://www.cnblogs.com/yunman/p/7112882.html?utm_source=itdadao&utm_medium=referral 1.AutoIT介 ...

  9. Java字符拼成图片(image-ASCII)

    目录 背景 代码思路 难点讲解 如何得到rgb 如何让不同颜色匹配不同字符 为什么我的图片只能打一半 OutOfMemoryError错误 为什么用汉字来打印图案会扭曲 装逼时刻 @(Java字符图片 ...

随机推荐

  1. linux系统基础网络配置

    1.修改主机名 临时方法: 退出当前shell重新登录即可生效.此法只能临时修改生效.重启系统后失效. 提示:很多人使用hostname主机名来修改,其实这个只是作为暂时的.重启后将恢复到配置前的主机 ...

  2. 配置SQL Server去使用 Windows的 Large-Page/Huge-Page allocations

    配置SQL Server去使用 Windows的 Large-Page/Huge-Page  allocations 目录表->页表->物理内存页 看这篇文章之前可以先看一下下面这篇文章 ...

  3. SQL Server中DateTime与DateTime2的区别

    DateTime字段类型对应的时间格式是 yyyy-MM-dd HH:mm:ss.fff ,3个f,精确到1毫秒(ms),示例 -- ::15.433 . DateTime2字段类型对应的时间格式是  ...

  4. 作业七:团队项目——Alpha版本冲刺阶段

      本次作业为期三周时间,要求各组结合所选项目并阅读教材<构建之法>第六章内容,完成项目的Alpha版本.本阶段的主要内容如下:(20分) 1. 每天组织一次站立会议,讨论每个成员的昨天进 ...

  5. Linux 进程

    Linux 进程 在用户空间,进程是由进程标识符(PID)表示的.从用户的角度来看,一个 PID 是一个数字值,可惟一标识一个进程.一个 PID 在进程的整个生命期间不会更改,但 PID 可以在进程销 ...

  6. 我所常用的ajax调用格式

    ajax: $.ajax({    type: "post",    datatype: "json",    contentType: "appli ...

  7. Linux驱动学习步骤(转载)

    1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ls ...

  8. javascript中对象函数继承的概念

    什么是函数对象?这个对象既是通常意义上的对象,又可以加上括号直接执行的函数. 产生函数对象的方式有两种:1.通过function关键字产生:var fn = function(){};2.实例化Fun ...

  9. paip.powerdesign cdm pdm文件 代码生成器 java web 页面 实现

    paip.powerdesign cdm pdm文件 代码生成器 java web 页面 实现 准备从pd cdm生成java web 页面...但是,ms无直接地生成软件.... 只好自己解析cdm ...

  10. python爬虫代码

    原创python爬虫代码 主要用到urllib2.BeautifulSoup模块 #encoding=utf-8 import re import requests import urllib2 im ...