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字符图片 ...
随机推荐
- React Native填坑之旅--动画
动画是提高用户体验不可缺少的一个元素.恰如其分的动画可以让用户更明确的感知当前的操作是什么. 无疑在使用React Native开发应用的时候也需要动画.这就需要知道RN都给我们提供了那些动画,和每个 ...
- Winpcap构建用户级网桥
Winpcap构建网桥 根据winpcap sdk中的user-level-bridge用户级网桥 |机器1 | |机器2 | | ...
- 使用的组件:Jcrop
JcropImage cropping for jQuery Jcrop 是一个功能强大的 jQuery 图像裁剪插件,结合后端程序(例如:PHP)可以快速的实现图片裁剪的功能. 官网地址:http: ...
- 使用的组件:ckeditor
老牌Web文本编辑器,无需多言. 官网地址:http://ckeditor.com/
- poj 1035 Spell checker
Spell checker Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u J ...
- [转]轻松解决oracle11g 空表不能exp导出的问题
转自:http://www.2cto.com/database/201109/105931.html oracle11g的新特性,数据条数是0时不分配segment,所以就不能被导出. 解决方法: 1 ...
- golang 远程传输文件
概述 之前有一篇介绍如何使用 golang 通过SSH协议来执行远程命令:golang 执行远程命令 同样,通过SSH协议也可以使用 golang 来远程传输文件. 除了 SSH 的库,为了传输文件, ...
- 把HDFS里的json数据转换成csv格式
1. 全景图 2. 用ListHDFS获取所有文件名 如果想重新再取一次,右健view state: 点击 clear state, 再运行,即可再次采集数据了. 3. 用FetchH ...
- os.popen(command)
command="/usr/local/sbin/xxx_cmd" os.popen(command) xxx_cmd是自己编译的二进制文件,如果不加上全路径/usr/local/ ...
- Linux:文件解压与压缩
文件打包与压缩 常见压缩文件格式: |文件后缀名 |说明| |.zip |zip程序打包压缩的文件| |.rar |rar程序压缩的文件| |.7z |7zip程序压缩的文件| |.tar |tar程 ...