`
defrag_sly
  • 浏览: 129759 次
  • 性别: 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
分享到:
评论

相关推荐

    java可用图像小图标

    5. **图标库**:除了自定义图标外,还有一些开源库提供丰富的图标资源,比如JavaFX的`javafx.scene.image.Image`类,或是专门为SWT设计的图标库,如Eclipse的`org.eclipse.jface.resource.ImageDescriptor`。...

    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

    C#性感美女动态图Gif转代码效果展示

    2. **提取帧信息**:GIF文件的每一帧都是一个位图,我们可以通过遍历GIF的ImageDescriptor和LocalColorTable来获取每一帧的像素数据和颜色信息。 3. **转换为代码表示**:将每一帧的像素数据转换为对应的代码表示。...

    保存TGA格式算法

    4. **数据存储**:TGA文件的像素数据可以以不同的顺序存储,`imageDescriptor`字段的低4位表示行顺序,0表示从底部到顶部,1表示从顶部到底部。高4位表示像素内部的字节顺序。 5. **数据编码**:像素数据通常以RGB...

    eclipse icons,用来开发rcp桌面应用程序

    使用这些图标时,开发者可以通过Eclipse的API来集成到自己的RCP应用中,例如使用`ImageDescriptor`和`Image`类加载和显示图标。这确保了应用与Eclipse平台的视觉一致性,增强了整体的专业感和用户体验。 在压缩包...

    Java SWT API参考(chm)

    6. **图像处理(Image Handling)**:SWT提供了加载和显示图像的能力,包括位图(Bitmap)、精灵(Sprite)和图标(ImageDescriptor),可轻松地将图形元素整合到应用程序中。 7. **打印支持(Printing Support)**...

    ArcGIS Server之经验谈

    解决这个问题的关键在于MapFunctionality的DisplaySettings.ImageDescriptor的ReturnMimeData属性。这个属性控制是否返回MIME数据而不是URL。当ReturnMimeData设置为False时,服务器将不再返回MIME数据,而是提供一...

    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 绘制线条 ...

    Vc实现的Gif解析源代码

    本资源“Vc实现的Gif解析源代码”是关于如何在Visual C++(Vc)环境下解析和显示GIF文件的详细源代码实现。通过这个资源,我们可以学习到GIF图像格式的基本原理,以及如何利用C++编程语言来处理这种格式。 首先,...

Global site tag (gtag.js) - Google Analytics