java利用透明的图片轮廓抠图
需要处理的图片:
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利用透明的图片轮廓抠图的更多相关文章
- java利用直方图实现图片对比
需求 实现两张图对比,找出其中不同的部分. 分析 首先将大图切片,分成许多小图片.然后进行逐个对比,并设定相似度阈值,判断是否是相同.最后整理,根据生成数组标记不同部分.如果切片足够小,便越能精确找出 ...
- java 生成透明背景图片
//开始绘图 graphics2d.setBackground(Color.WHITE); graphics2d.clearRect(0, 0, width, height); graphics2d. ...
- Java利用poi生成word(包含插入图片,动态表格,行合并)
转(小改): Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插 ...
- 利用box-shadow实现伪边框透明到图片
前阵子突然看到了一个效果,一张图片,有一个边框,但是边框可以透明到图片.直接上图 贴代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr ...
- Java+jquery实现裁剪图片上传到服务器
大体分两步: 1.利用jquery裁剪图片,把裁剪到的几个点传入后端 2.利用前端传入的几个点,来裁剪图片 首先,用到一个jquery的插件 imgAreaSelect 实例及插件下载地址:http: ...
- java 利用spring JavaMailSenderImpl发送邮件,支持普通文本、附件、html、velocity模板
java 利用spring JavaMailSenderImpl发送邮件,支持普通文本.附件.html.velocity模板 博客分类: Java Spring 本文主要介绍利用JavaMailS ...
- 谈谈Java利用原始HttpURLConnection发送POST数据
这篇文章主要给大家介绍java利用原始httpUrlConnection发送post数据,设计到httpUrlConnection类的相关知识,感兴趣的朋友跟着小编一起学习吧 URLConnectio ...
- selenium+java利用AutoIT实现文件上传
转自https://www.cnblogs.com/yunman/p/7112882.html?utm_source=itdadao&utm_medium=referral 1.AutoIT介 ...
- Java字符拼成图片(image-ASCII)
目录 背景 代码思路 难点讲解 如何得到rgb 如何让不同颜色匹配不同字符 为什么我的图片只能打一半 OutOfMemoryError错误 为什么用汉字来打印图案会扭曲 装逼时刻 @(Java字符图片 ...
随机推荐
- Android性能优化方法(四)
在一个应用程序中,一般都会存在多个Activity,每个Activity对应着一个UI布局文件.一般来说,为了保持不同窗口之间的风格统一,在这些UI布局文件中,几乎肯定会用到很多相同的布局.如果我们在 ...
- codeforces 424D
题意:给定n,m<=300的矩阵,然后求一个长宽大于2的矩形,使得是从左上角位置开始逆时针绕边框一圈的时间最少.时间的计算是:给定3个数tu,tp, td,路径上数字增加为tu,相等为tp否则为 ...
- 部分具有统计功能的TSQL语句(例如DBCC语句,全局函数,系统存储过程)
部分具有统计功能的TSQL语句(例如DBCC语句,全局函数,系统存储过程) 这些功能也能帮助用户了解和监控SQLSERVER的运行情况 DBCC语句,DBCC语句是SQL2005的数据库控制台命令 D ...
- Dynamic CRM 2013学习笔记(七)追踪、监控及性能优化
本文将介绍CRM的三个内容追踪.监控及性能优化.追踪是CRM里一个很有用的功能,它能为我们的CRM调试或解决错误.警告提供有价值的信息:我们可以用window的性能监控工具来了解CRM的性能状况:最后 ...
- Windows7上搭建Cocos2d-x 3.1.1开发环境
前言 现在,越来越多的公司采用Cocos2d-x 3.0来开发游戏了,但是现在这样的文章并不多,所以打算写一系列来帮助初学者快速掌握Cocos2d-x 3.0.首先就从开发环境的大家说起吧. 开发工具 ...
- EF Code First Migration总结
开启Migration 1. 通过 Tools->Nuget Package Manager->Package Manager Console 打开Package Manager Cons ...
- hibernate懒加载(转载)
http://blog.csdn.net/sanjy523892105/article/details/7071139 懒加载详解 懒加载为Hibernate中比较常用的特性之一,下面我们详细来了解下 ...
- servlet/jsp GET/POST
GET请求方式 当需要向服务器请求指定的资源时使用的方法 它不应该用于一些会造成副作用的操作中(在网络应用中用它来提交请求是一种常见的错误用法) 什么情况浏览器发送get请求 -在地址栏输入一个地址 ...
- verify.js使用验证插件使用
github:https://github.com/52fhy/verify.js 首先引入js,最好拷贝verify整个目录,因为里面有图标. <script src="verify ...
- .NET Remoting学习笔记(一)概念
目录 .NET Remoting学习笔记(一)概念 .NET Remoting学习笔记(二)激活方式 .NET Remoting学习笔记(三)信道 背景 自接触编程以来,一直听过这个名词Remotin ...