`
defrag_sly
  • 浏览: 131397 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于image,ImageDescriptor,imageRegistry

阅读更多
相信不需要多说,大家都明白调用本地资源例如(icon)这类的资源是需要消耗很多性能的。SWT提供了Image这个对象,如果大家看看Image这个类,就会发现,对与图片的颜色,大小,色调等等所有的图形信息,封装到了ImageData(其实ImageData里还有个PaletteData,这个对象占用了很多资源)里面。也就是说每创建一次image就需要重新构筑一次ImageData。所以对于同一图片如果只创建一次,就会对效率有很大的提高。相信这是所有人都希望做的的事。
所以SWT对image提供了ImageDescriptor进行描述或者说代理,imageRegistry进行管理。在我们的实际开发中发现许多人使用方式不同,就会产生效率上的差异。
以下我对几种不同的使用方式进行了测试,有些错误方式甚至在eclipse源代码中都有使用。
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;

public class ImageTester {

	private static int size;
	private static final String imagePath = "F:/slyworkspace/myTest/gefTree/aaaaaaaa/icons/Control_Treeview.jpg";

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		size = 1000;
		ImageTester imageTester = new ImageTester();
		System.out.println("===========createByDescriptor=============");
		long start = System.currentTimeMillis();
		System.out.println("start : " + start);
		for (int i = 0; i < size; i++)
			imageTester.createByDescriptor();
		long end = System.currentTimeMillis();
		System.out.println("end : " + end);
		System.out.println("time : " + (end - start));

		// =================================================
		System.out.println("===========createByImageData=============");
		start = System.currentTimeMillis();
		System.out.println("start : " + start);
		for (int i = 0; i < size; i++)
			imageTester.createByImageData();
		end = System.currentTimeMillis();
		System.out.println("end : " + end);
		System.out.println("time : " + (end - start));

		// =================================================
		System.out.println("===========createByRegistry=============");
		start = System.currentTimeMillis();
		System.out.println("start : " + start);

		for (int i = 0; i < size; i++)
			imageTester.createByRegistry();
		end = System.currentTimeMillis();
		System.out.println("end : " + end);
		System.out.println("time : " + (end - start));

		// =================================================
		System.out.println("===========createByRegistryWrong=============");
		start = System.currentTimeMillis();
		System.out.println("start : " + start);
		for (int i = 0; i < size; i++)
			imageTester.createByRegistryWrong();
		end = System.currentTimeMillis();
		System.out.println("end : " + end);
		System.out.println("time : " + (end - start));
	}

	public Image createByDescriptor() {
		URL fullPathString = null;
		try {
			fullPathString = new File(imagePath).toURL();
		} catch (MalformedURLException e) {
			return null;
		}
		ImageDescriptor desc = ImageDescriptor.createFromURL(fullPathString);
		Image createImage = desc.createImage();
		return createImage;
	}

	public Image createByImageData() {
		Image image = new Image(Display.getCurrent(), new ImageData(imagePath));
		return image;
	}

	public Image createByRegistry() {

		ImageRegistry imageRegistry = JFaceResources.getImageRegistry();
		String key = "ImageTestter";
		Image image = imageRegistry.get(key);
		if (image == null) {
			URL fullPathString = null;
			try {
				fullPathString = new File(imagePath).toURL();
			} catch (MalformedURLException e) {
				return null;
			}
			ImageDescriptor imageDescriptor = ImageDescriptor
					.createFromURL(fullPathString);
			if (imageDescriptor != null) {
				imageRegistry.put(key, imageDescriptor);
				image = imageRegistry.get(key);
			}
		}
		return image;
	}

	public Image createByRegistryWrong() {
		ImageRegistry imageRegistry = JFaceResources.getImageRegistry();
		String key = "ImageTestter";
		ImageDescriptor descriptor = imageRegistry.getDescriptor(key);
		if (descriptor == null) {
			URL fullPathString = null;
			try {
				fullPathString = new File(imagePath).toURL();
			} catch (MalformedURLException e) {
				return null;
			}
			ImageDescriptor imageDescriptor = ImageDescriptor
					.createFromURL(fullPathString);
			if (imageDescriptor != null) {
				imageRegistry.put(key, imageDescriptor);
			}
		}
		descriptor = imageRegistry.getDescriptor(key);

		Image createImage = descriptor.createImage();
		return createImage;
	}
}



测试的结果:

===========createByDescriptor=============
start : 1235712247921
end : 1235712254859
time : 6938
===========createByImageData=============
start : 1235712254859
end : 1235712261187
time : 6328
===========createByRegistry=============
start : 1235712261187
end : 1235712261468
time : 281
===========createByRegistryWrong=============
start : 1235712261468
end : 1235712267937
time : 6469



从结果可以发现,使用createByRegistry这个方法是极大的提高了效率,原因是:ImageRegistry内维护了一个key-->descriptor&image的一个map。将image缓存了起来。
相信绝大部分人不会用createByImageData这个方法,但是大家可能发现为什么这个方法比createByDescriptor还要快呢?这是由于Descriptor.create其实和new Image()是一样的,并没有把image缓存。相反createByDescriptor这个方法错误的使用了Descriptor浪费了时间。最后一个方法createByRegistryWrong是我发现大多数人最容易错的使用方法,只是简单的将Descriptor缓存起来但是在得到image时仍然与createByImageData没有差别,这也浪费了一些时间,size的增加createByImageData与createByRegistryWrong会越来越接近,但是与createByDescriptor会越来越大。
方法createByRegistry无疑是效率最优的方法。
ps:在我的机器上size=10000时候,甚至出现了没有足够handls的情况。(双盒1g的哦)
虽然以上的测试仅仅是一些极限的测试,对于同一图片使用1000次的情况,在eclipse中或许并不常见,所以才会出现eclipse的源代码中存在错误的使用方法吧。
不过效率的差别的确真的很明显。
总结一下,使用中Image类对于我们来讲是禁止使用的,如果需要image的一些信息,需要从Descriptor对象中获得,控制ImageData对象的后加载,需要image对象的时候利用Registry。
最好的方式是将Descriptor放到Registry中,使用Registry同一管理。
3
0
分享到:
评论

相关推荐

    Eclipse下SWT图形界面开发指南(2)

    **添加到注册表**:调用`ImageRegistry.put()`方法将图像对象添加到注册表中。 3. **获取图像**:通过`ImageRegistry.get()`方法从注册表中获取图像对象。 4. **释放资源**:在不再需要时,调用`Image.dispose()`...

    SWT(JFace) 文本编辑器 实现代码

    代码如下: 实现1: BasicEditor.java 代码如下:package swt_jface.demo5; import java.io.BufferedReader; import java.io.File; import java.io.... import org.eclipse.jface.resource.ImageRegistry; import

    Eclipse_Swt_Jface_核心应用_部分19

    12.5.2 图像类(Image) 254 12.5.3 图像数据类(ImageData) 255 12.5.4 保存图像类(ImageLoader) 256 12.5.5 Eclipse的图标 256 12.6 SWT绘图 257 12.6.1 使用绘制对象的方法 257 12.6.2 绘制线条 ...

    智慧消防大数据解决方案PPT(19页).pptx

    智慧消防安全与应急管理是现代城市安全管理的重要组成部分,随着城市化进程的加速,传统消防安全管理面临着诸多挑战,如消防安全责任制度落实不到位、消防设施日常管理不足、消防警力不足等。这些问题不仅制约了消防安全管理水平的提升,也给城市的安全运行带来了潜在风险。然而,物联网和智慧城市技术的快速发展为解决这些问题提供了新的思路和方法。智慧消防作为物联网和智慧城市技术结合的创新产物,正在成为社会消防安全管理的新趋势。 智慧消防的核心在于通过技术创新实现消防安全管理的智能化和自动化。其主要应用包括物联网消防安全监管平台、城市消防远程监控系统、智慧消防平台等,这些系统利用先进的技术手段,如GPS、GSM、GIS等,实现了对消防设施的实时监控、智能巡检和精准定位。例如,单兵定位方案通过信标点定位和微惯导加蓝牙辅助定位技术,能够精确掌握消防人员的位置信息,从而提高救援效率和安全性。智慧消防不仅提升了消防设施的管理质量,还优化了社会消防安全管理资源的配置,降低了管理成本。此外,智慧消防的应用还弥补了传统消防安全管理中数据处理方式落后、值班制度执行不彻底等问题,赋予了建筑消防设施智能化、自动化的能力。 尽管智慧消防技术在社会消防安全管理工作中的应用已经展现出巨大的潜力和优势,但目前仍处于实践探索阶段。相关职能部门和研究企业需要加大研究开发力度,进一步完善系统的功能与实效性。智慧消防的发展既面临风险,也充满机遇。当前,社会消防安全管理工作中仍存在制度执行不彻底、消防设施日常维护不到位等问题,而智慧消防理念与技术的应用可以有效弥补这些弊端,提高消防安全管理的自动化与智能化水平。随着智慧城市理念的不断发展和实践,智慧消防将成为推动社会消防安全管理工作与城市化进程同步发展的关键力量。

    scratch少儿编程逻辑思维游戏源码-黄金时间.zip

    scratch少儿编程逻辑思维游戏源码-黄金时间.zip

    scratch少儿编程逻辑思维游戏源码-反冲枪.zip

    scratch少儿编程逻辑思维游戏源码-反冲枪.zip

    FlinkCDC3.2.1连接oracle11g的jar依赖

    将jar包解压放到flink的lib目录下

    飞机大战:精灵动力学与弹幕系统的数学交响

    在二维空战游戏的华丽表象之下,精灵动画与子弹系统构建起精密的数学宇宙。本文将深入解析飞机运动学、弹幕生成算法和渲染流水线优化策略,揭示经典空战游戏背后的连续介质力学与离散事件处理的完美融合。

    基于MPC轨迹跟踪技术的圆形道路运动学Carsim与Simulink联合仿真研究

    内容概要:本文详细介绍了利用模型预测控制(MPC)技术,在给定圆形道路条件下进行车辆轨迹跟踪的研究。主要内容涵盖MPC轨迹跟踪的基本原理、圆形道路的轨迹规划、MPC控制器的设计及其在carsim和simulink平台上的联合仿真。文中还展示了部分用于MPC控制器设计的Python代码片段,帮助读者更好地理解和实现相关技术。最后,文章总结了MPC在车辆控制系统中的重要性和未来的发展前景。 适合人群:从事车辆工程、自动化控制领域的研究人员和技术人员,特别是对MPC技术和车辆仿真感兴趣的读者。 使用场景及目标:适用于希望深入了解MPC轨迹跟踪技术及其在车辆控制系统中应用的专业人士。目标是通过理论与仿真的结合,提升对MPC控制器的理解和实际操作能力。 其他说明:文章不仅提供了详细的理论解释,还包括具体的代码实现和仿真步骤,有助于读者从理论到实践全面掌握MPC轨迹跟踪技术。

    水厂供水泵房自动化控制系统:PLC与触摸屏程序及组态软件的应用实例

    内容概要:本文详细介绍了某水厂供水泵房自动化控制系统的具体实施情况,涵盖PLC程序、触摸屏程序以及组态软件程序的设计与应用。PLC部分着重于I/O分配、压力值转换及其量程校验,确保系统稳定性和安全性;触摸屏程序则涉及隐藏菜单设置,用于调试阶段的功能访问限制;组态软件关注报警处理机制,优化后的报警触发逻辑提高了系统的响应速度。此外,还分享了一些现场调试的经验和技术细节,如通讯问题解决方法、硬件安装注意事项等。 适合人群:从事工业自动化领域的工程师、技术人员,尤其是对PLC编程、HMI界面设计和SCADA系统有研究兴趣的专业人士。 使用场景及目标:适用于新建或改造水厂及其他类似行业的自动化工程项目规划与实施过程中,旨在帮助相关人员更好地理解和掌握相关技术和最佳实践。 其他说明:文中提到的具体数值和配置仅供参考,在实际项目中需要根据具体情况调整。同时强调了工程实践中的一些常见误区和应对措施,为后续项目的顺利进行提供了宝贵的经验借鉴。

    scratch少儿编程逻辑思维游戏源码-节日贺卡.zip

    scratch少儿编程逻辑思维游戏源码-节日贺卡.zip

    少儿编程scratch项目源代码文件案例素材-铁弹.zip

    少儿编程scratch项目源代码文件案例素材-铁弹.zip

    基于springboot的“地方废物回收机构管理系统 ”的设计与实现(源码+数据库+文档+PPT).zip

    # 基于springboot的“地方废物回收机构管理系统 ”的设计与实现(源码+数据库+文档+PPT) - 开发语言:Java - 数据库:MySQL - 技术:springboot - 工具:IDEA/Ecilpse、Navicat、Maven 管理员功能: 管理员登陆后,主要模块包括首页、个人中心、员工管理、员工请假管理、销假申请管理、工作日志管理、员工工资管理、员工任务管理、任务汇报管理、设备信息管理、设备借用管理、设备归还管理、设备报修管理、维修入库管理、员工打卡管理、员工评价管理、回收价格管理、宿舍信息管理、宿舍入住管理、宿舍搬出管理、管理员管理、系统管理等功能。 员工功能: 员工登陆后,主要模块包括首页、个人中心、员工请假管理、销假申请管理、工作日志管理、员工工资管理、员工任务管理、任务汇报管理、设备信息管理、设备借用管理、设备归还管理、设备报修管理、维修入库管理、员工打卡管理、员工评价管理、回收价格管理、宿舍入住管理、宿舍搬出管理等功能。

    中国通信企业协会(李农):大模型之舞:客服行业高质量发展的新探索.pdf

    中国通信企业协会(李农):大模型之舞:客服行业高质量发展的新探索

    云开发Wetour旅游打卡广场微信小程序源码.zip

    云开发Wetour旅游打卡广场微信小程序源码,使用云开发技术,taro 构建 主要功能有:景点列表、景点详情、打卡记录、打卡成功、评论、景点地图、 景点导航、行程规划、行程线路等,注意搭建时候不兼容taro最新版本,请使用tarov1.3.18,后台为云开发管理后台。

    双有源桥DAB控制技术:功率均衡与动态特性提升的MATLAB/Simulink仿真及硬件实现

    内容概要:本文深入探讨了双有源桥(DAB)控制技术,涵盖单相搭建、单移相仿真、拓展移相、MPC(模型预测控制)、功率均衡及回流功率抑制等多个方面。文章不仅提供了详尽的理论分析,如数学模型、小信号建模和级联功率均衡,还展示了MATLAB/Simulink仿真结果和硬件实验平台的搭建细节。所有仿真数据、原理图、三维图均已完成,便于直接使用和进一步调整。此外,文中还包括了专利格式的技术文档,详细描述了单相回流功率抑制的创新点和技术特点。 适合人群:电力电子工程师、科研人员、高校教师及研究生,特别是从事双有源桥控制技术和功率转换研究的专业人士。 使用场景及目标:适用于需要深入了解双有源桥控制技术及其应用的研究人员,帮助他们掌握从理论到实践的完整流程,包括仿真验证和硬件实现。目标是提升系统的功率均衡能力和动态响应性能,解决回流功率问题。 其他说明:文章提供了丰富的参考资料,包括详细的仿真步骤、硬件选型指南、专利申请指导等,有助于读者快速上手并应用于实际项目中。

    scratch少儿编程逻辑思维游戏源码-尖刺.zip

    scratch少儿编程逻辑思维游戏源码-尖刺.zip

    汽车动力学建模与仿真:基于CarSim和Simulink联仿平台的空间位姿及速度时变研究

    内容概要:本文探讨了利用CarSim和Simulink进行车辆动力学模型的联合仿真,重点在于分析汽车在不同路况和驾驶条件下,空间位姿和速度随时间的变化情况。文章首先介绍了车辆动力学模型的概念及其重要性,随后详细讲解了CarSim和Simulink各自的功能特点以及它们联仿的优势。文中还展示了具体的Matlab代码片段,演示了如何设置仿真参数、导入模型、运行仿真并记录数据。最后,通过对仿真结果的分析,揭示了不同因素对汽车运动行为的影响,为汽车设计和性能优化提供了理论依据和技术手段。 适合人群:从事汽车工程、车辆动力学研究的专业人士,以及对汽车仿真感兴趣的科研人员和学生。 使用场景及目标:适用于希望深入了解车辆动力学特性的研究人员,旨在帮助他们掌握CarSim和Simulink联仿方法,提高汽车设计和性能分析的能力。 其他说明:文章不仅提供了详细的理论解释,还包括实际操作步骤和代码实例,便于读者快速上手实践。

    Requirements

    Requirements

Global site tag (gtag.js) - Google Analytics