获取图片的尺寸有三种方法 将整个图片文件加载成 BufferedImage 后获取其尺寸 用 ImageReader 快捷获取 即下文所陈述的方式 做过简陋的测试效率自 至 逐步递增 ImageInfojava /** * @author kodeyang */ public class ImageInfo { private int height; private int width; public ImageInfo(int height int width) { super(); thisheight = height; thiswidth = width; } public int getWidth() { return width; } public int getHeight() { return height; } @Override public String toString() { return height: + height + width: + width; } } import javaioIOException; import javaioInputStream; /** * @author yangwei * */ public class JpegInfoReader { private static final byte TAG_START = (byte) xff; private static final byte START_OF_IMAGE = (byte) xd; private static final byte END_OF_IMAGE = (byte) xd; private static final byte START_OF_FRAME = (byte) xc; private static final byte RESTART_MODULO_START = (byte) xd; private static final byte RESTART_MODULO_END = (byte) xd; private static final byte START_OF_SCAN = (byte) xda; public static ImageInfo getImageInfo(InputStream in) throws IOException { // : store JPEG tag // : store JPEG tag length // : store JPEG image height // : store JPEG image width byte[] seg = new byte[]; // read JPEG START_OF_IMAGE tag if (inread(seg ) == ) { return null; } // if the first two bytes is not xff xd // that is the image format is not JPEG if (seg[] != TAG_START || seg[] != START_OF_IMAGE) { return null; } while (true) { // read JPEG data tag offset must be xff if (inread(seg ) == ) { return null; } // if tag does not start with xff // the image format is not JPEG if (seg[] != TAG_START) { return null; } // Ignore JPEG RESTART_MODULO tag if (seg[] >= RESTART_MODULO_START && seg[] <= RESTART_MODULO_END) { continue; } // find JPEG format START_OF_SCAN part // data that starts with poisition is JPEG compression image data // that never contains image meta information if (seg[] == START_OF_SCAN) { return null; } // find JPEG format END_OF_IMAGE tag finish scan if (seg[] == END_OF_IMAGE) { return null; } // read JPEG data tag length if (inread(seg ) == ) { return null; } // find START_OF_FRAME tag if (seg[] == START_OF_FRAME) { break; } // skip JPEG data segement byte[] skip = new byte[toInt(seg ) ]; if (inread(skip) == ) { return null; } } // ignore JPEG image precision byte if (inread() == ) { return null; } // read JPEG image height and width bytes if (inread(seg ) == ) { return null; } return new ImageInfo(toInt(seg ) toInt(seg )); } private static int toInt(byte[] bys int start) { return ((bys[start] & xff) << ) | (bys[start + ] & xff); } } import javaioFileInputStream; import javaioIOException; import javaioInputStream; /** * @author yangwei * */ public class JpegInfoReaderUsage { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { InputStream in = null; try { in = new FileInputStream(d:/imagesjpg); ImageInfo info = JpegInfoReadergetImageInfo(in); Systemoutprintln(info); } finally { if (in != null) { inclose(); } } } } 提问 class 前面带 static 是什么用法呢 另外宽高都拿到了为什么还要将 宽高丢到一个 ImageInfo 对象里面呢直接使用整形数组的结果不是更快捷? 回答 内部类使用 static 的话一般说明这个内部类不需要使用到外部类中的任何成员变量或者成员方法也就是说这个内部类相对于较为独立 如果有需要使用到外部类中数据的话则需要把 static 去掉不对外部类数据进行引用时内部类应使用 static 类 对于这个问题举个很简单的例子如果我还想获取图像长宽的 DPI 信息以及颜色深度信息或者是 JPEG 中 Exif 信息的话那使用 int[] 就没办法表示了 在面向对象程序设计中返回值应尽量少使用 int[] String[] Map<String Object> 之类的返回值因为这样的返回值不是自描述的 为什么 int[] 是表示长度呢?int[] 就不能表示宽度么? 我很能理解你认为返回 int[] 的理由是什么可能是因为 new 一个对象比较耗时和占用内存空间吧? 实际上并不是这样的new 一个对象而且这个类的构造中没有任何复杂耗时的操作对于系统消耗来说可以忽略不计而对于 HotSpot 的 JVM 而言其内存分配的速度是大于 C 语言中 malloc 的内存分配速度 在 HotSpot 的 JVM 中一个 new 操作只占用了十几个 CPU 指令的时间new 一个对象和 new 一个 int 数据的效率是等价的 另外new 一个对象所分配的内存更是可以忽略不计了只是在 JVM 的 PermGen 方法区中多存放一些类的信息以及方法的信息 |