通过纯Java的方式往一张底图(地图)上添加小图片(布点),发现效果并不理想。
何为纯java方式?就是说这些操作不需要依赖于c/c++库,具有良好的跨平台性,要求不仅仅能运行在Windows、Linux、Unix三大平台之上,也可以用作Android等移动平台之上。
下面是往一张底图上添加小图片(即图像合并)的测试的数据:
合并小图数量 | 测试次数 | 100(张) | 1000(张) | 10000(张) |
耗时(毫秒) | 第1次 | 2003 | 15334 | 153010 |
第2次 | 1792 | 15200 | 153340 | |
第3次 | 1869 | 15236 | 152673 | |
第4次 | 1747 | 15903 | 154978 | |
第5次 | 1871 | 16028 | 156506 | |
第6次 | 1793 | 15545 | 154854 | |
平均耗时(毫秒) | 1845.833 | 15541 | 154226.8 | |
换算为秒 | 1.845833 | 15.541 | 154.2268 |
往一张底图上合并小图100张平均耗时 1.845833秒,
往一张底图上合并小图1000张平均耗时 15.541秒,
往一张底图上合并小图10000张平均耗时 154.2268秒。
感觉这样的效率还是太低了,无法满足数以万计的底图布点需求。据说,一段高效的c++程序完成数以万计的地图布点任务也就需要大概一两秒的时间(听一位颇有经验的高手说的,本人未曾尝试)。
这次终于感受到java和c/c++在效率上的差距了!
那么是不是要牺牲跨平台性了,用Jmagick尝试一下?此问题有待讨论…
--------------------------------------------Jmagick尝试图像合并,利用了ImageMagick的命令来调用命令合并图像的方式---------------------------------------------------------------
public void compositeImageList(List additionImageList,String srcImagePath,String toImagePath){
/*
*命令格式:composite -geometry +100+150 additionImagePath srcImagePath toImagePath
*将图像additionImagePath附加在图像srcImagePath上的100,150坐标处,输出为toImagePath图像
*/
//String command = "composite -geometry +100+150 D:/test/fileSource/007.png D:/test/fileSource/002.jpg D:/test/desk/rose-002.png";
if(additionImageList!=null){
System.out.println(additionImageList.size());
for(int i=0;i<additionImageList.size();i++){
String[] additionImageInfo = (String[]) additionImageList.get(i);
int x = Integer.parseInt(additionImageInfo[0]);
int y = Integer.parseInt(additionImageInfo[1]);
String additionImagePath = additionImageInfo[2];
StringBuffer command = new StringBuffer("");
command.append("composite -geometry ");
command.append("+"+x+"+"+y+" ");
command.append(additionImagePath+" ");
command.append(srcImagePath+" ");
command.append(toImagePath);
System.out.println(command);
String[] str = {command.toString()};
JmagickTest.exec(str);
}
}
}
public static void main(String[] args) {
JmagickTest imageObj = new JmagickTest();//调用合并图像方法所在的类
try {
String negativeImagePath = "D:/test/fileSource/001.jpg";
String toPath = "D:/test/fileSource/001.jpg";
String additionImagePath = "D:/test/fileSource/007.png";
List additionImageList = new ArrayList();
int count = 0;
Random rand = new Random();
for(int i=0;i<10000;i++){
int x = rand.nextInt(1020);
String xStr = x+"";
int y = rand.nextInt(760);
String yStr = y +"";
String[] str = {xStr,yStr,additionImagePath};
additionImageList.add(str);
}
long start = System.currentTimeMillis();
imageObj.mergeImageList(negativeImagePath, additionImageList,"jpg", toPath);
long end = System.currentTimeMillis();
System.out.println(end-start);
} catch (Exception e) {
e.printStackTrace();
}
}
以下是测试的数据:
图像数量 合并耗费时间(ms)
1---- 140
10---- 1419
100---- 13912
1000---- 137965
10000 ---- 1392095
二者对比,发现以ImageMigick命令合并图像的方式,效率明显低于JDK 的ImageIO处理方式,并且在跨平台上也逊色于纯java的方式。
---------------------------jdk版本(jre版本)版本不同,运行效率的差异
请参考我的另一篇博文:http://blog.csdn.net/hu_shengyang/article/details/7628290