转载地址 http://blog.jdk5.com/zh/java-get-image-size-without-loading-the-whole-data/

利用Java类,获取图片的类型,宽度和高度,方法有多种,比如:

  1. BufferedImage bimg = ImageIO.read(new File("d:\\image\\org.jpg"));
  2. int width = bimg.getWidth();
  3. int height = bimg.getHeight();

但这方法将整张图片都加载到了内存,如果那些图片比较大,无疑将增加服务的压力。

下面推荐一个更简单的方法,不需要加载整个图片,从而节省内存空间。

代码如下:

  1. package com.jiafuwei.java;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8.  
  9. public class SimpleImageInfo {
  10. private int height;
  11. private int width;
  12. private String mimeType;
  13.  
  14. public SimpleImageInfo(File file) throws IOException {
  15. InputStream is = new FileInputStream(file);
  16. try {
  17. processStream(is);
  18. } finally {
  19. is.close();
  20. }
  21. }
  22.  
  23. public SimpleImageInfo(InputStream is) throws IOException {
  24. processStream(is);
  25. }
  26.  
  27. public SimpleImageInfo(byte[] bytes) throws IOException {
  28. InputStream is = new ByteArrayInputStream(bytes);
  29. try {
  30. processStream(is);
  31. } finally {
  32. is.close();
  33. }
  34. }
  35.  
  36. private void processStream(InputStream is) throws IOException {
  37. int c1 = is.read();
  38. int c2 = is.read();
  39. int c3 = is.read();
  40.  
  41. mimeType = null;
  42. width = height = -1;
  43.  
  44. if (c1 == 'G' && c2 == 'I' && c3 == 'F') { // GIF
  45. is.skip(3);
  46. width = readInt(is,2,false);
  47. height = readInt(is,2,false);
  48. mimeType = "image/gif";
  49. } else if (c1 == 0xFF && c2 == 0xD8) { // JPG
  50. while (c3 == 255) {
  51. int marker = is.read();
  52. int len = readInt(is,2,true);
  53. if (marker == 192 || marker == 193 || marker == 194) {
  54. is.skip(1);
  55. height = readInt(is,2,true);
  56. width = readInt(is,2,true);
  57. mimeType = "image/jpeg";
  58. break;
  59. }
  60. is.skip(len - 2);
  61. c3 = is.read();
  62. }
  63. } else if (c1 == 137 && c2 == 80 && c3 == 78) { // PNG
  64. is.skip(15);
  65. width = readInt(is,2,true);
  66. is.skip(2);
  67. height = readInt(is,2,true);
  68. mimeType = "image/png";
  69. } else if (c1 == 66 && c2 == 77) { // BMP
  70. is.skip(15);
  71. width = readInt(is,2,false);
  72. is.skip(2);
  73. height = readInt(is,2,false);
  74. mimeType = "image/bmp";
  75. } else {
  76. int c4 = is.read();
  77. if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
  78. || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { //TIFF
  79. boolean bigEndian = c1 == 'M';
  80. int ifd = 0;
  81. int entries;
  82. ifd = readInt(is,4,bigEndian);
  83. is.skip(ifd - 8);
  84. entries = readInt(is,2,bigEndian);
  85. for (int i = 1; i <= entries; i++) {
  86. int tag = readInt(is,2,bigEndian);
  87. int fieldType = readInt(is,2,bigEndian);
  88. int valOffset;
  89. if ((fieldType == 3 || fieldType == 8)) {
  90. valOffset = readInt(is,2,bigEndian);
  91. is.skip(2);
  92. } else {
  93. valOffset = readInt(is,4,bigEndian);
  94. }
  95. if (tag == 256) {
  96. width = valOffset;
  97. } else if (tag == 257) {
  98. height = valOffset;
  99. }
  100. if (width != -1 && height != -1) {
  101. mimeType = "image/tiff";
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. if (mimeType == null) {
  108. throw new IOException("Unsupported image type");
  109. }
  110. }
  111.  
  112. private int readInt(InputStream is, int noOfBytes, boolean bigEndian) throws IOException {
  113. int ret = 0;
  114. int sv = bigEndian ? ((noOfBytes - 1) * 8) : 0;
  115. int cnt = bigEndian ? -8 : 8;
  116. for(int i=0;i<noOfBytes;i++) {
  117. ret |= is.read() << sv;
  118. sv += cnt;
  119. }
  120. return ret;
  121. }
  122.  
  123. public int getHeight() {
  124. return height;
  125. }
  126.  
  127. public void setHeight(int height) {
  128. this.height = height;
  129. }
  130.  
  131. public int getWidth() {
  132. return width;
  133. }
  134.  
  135. public void setWidth(int width) {
  136. this.width = width;
  137. }
  138.  
  139. public String getMimeType() {
  140. return mimeType;
  141. }
  142.  
  143. public void setMimeType(String mimeType) {
  144. this.mimeType = mimeType;
  145. }
  146.  
  147. @Override
  148. public String toString() {
  149. return "MIME Type : " + mimeType + "\t Width : " + width
  150. + "\t Height : " + height;
  151. }
  152. }
  1. package com.jiafuwei.java;
  2.  
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.InputStream;
  6.  
  7. public class Test {
  8. public static void main(String[] args) {
  9. try {
  10. File f = new File("E:\\1.jpg");
  11. // Getting image data from a InputStream
  12. FileInputStream b = new FileInputStream(f);
  13. SimpleImageInfo imageInfo = new SimpleImageInfo(b);
  14. System.out.println(imageInfo);
  15. // Getting image data from a file
  16. imageInfo = new SimpleImageInfo(f);
  17. System.out.println(imageInfo);
  18. // Getting image data from a byte array
  19. byte[] buffer = new byte[1024 * 6];
  20. InputStream is = new FileInputStream(f);
  21. while (is.read(buffer) == -1) {}
  22. is.close();
  23. imageInfo = new SimpleImageInfo(buffer);
  24. System.out.println(imageInfo);
  25. } catch (Exception e) {
  26. System.out.println(e.getMessage());
  27. }
  28. }
  29. }

Java不需要加载整张图片而获取图片的大小的更多相关文章

  1. 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】

    目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...

  2. Android Bitmap 全面解析(二)加载多张图片的缓存处理

    一般少量图片是很少出现OOM异常的,除非单张图片过~大~ 那么就可以用教程一里面的方法了通常应用场景是listview列表加载多张图片,为了提高效率一般要缓存一部分图片,这样方便再次查看时能快速显示~ ...

  3. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  4. Java中类的加载、连接和初始化

    Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...

  5. Java类的加载、链接和初始化

    一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...

  6. java 类的加载,链接,初始化

    本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...

  7. java 中类的加载顺序(转)

    1.虚拟机在首次加载Java类时,会对静态初始化块.静态成员变量.静态方法进行一次初始化 2.只有在调用new方法时才会创建类的实例 3.类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始 ...

  8. 【Java基础】Java类的加载和对象创建流程的详细分析

    相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 package ...

  9. java程序的加载过程

    昨天笔试阿里有个求java程序加载过程的题目很是复杂,回来研究了好久才有点明白,整理一下.原题代码如下,判断输出: public class StaticTest { public static in ...

随机推荐

  1. xml解析之stax

    博文引自:http://zangweiren.iteye.com/blog/647334 Java 6.0对XML支持的新特性有许多方面.比如StAX.针对XML-Web服务的Java架构(JAX-W ...

  2. python——matplotlib图像的基本处理

    1.绘制图像中的点和线 from PIL import Image from pylab import * im = array(Image.open('E:\Python\meinv.jpg')) ...

  3. SVN 的基本用法

    克隆远程库 # svn checkout $URL --username=$userName 显示库信息 # svn info 显示库状态 # svn status 将文件纳入版本管理 # svn a ...

  4. 05,Python网络爬虫之三种数据解析方式

    回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据 ...

  5. mysql 中的基本用法,以及日期的转换

    1.mysql int(10) int 类型长度4个字节,大约表示2^32数字,10代表的是显示长度,一般和FILLZERO约束一起使用,如果没有达到该长度,填充02-->000000002 m ...

  6. SetConsoleCtrlHandler

    Excerpt: Registering a Control Handler Function   This is an example of the SetConsoleCtrlHandler fu ...

  7. DataSource的设置

    1.Centos和redhat,Fedora等版本无须设置,直接在cloud.cfg指定,默认是EC2 datasource_list: ['ConfigDrive','OpenStack'] 2.u ...

  8. [OpenCV]Mat类详解

    http://blog.csdn.net/yang_xian521/article/details/7107786 Preface Mat:Matrix Mat类可以被看做是opencv中C++版本的 ...

  9. 原始套接字--icmp相关

    icmp请求 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <uni ...

  10. django之HTTPResponse和JsonResponse详解

    HttpResponse对象 Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数.那么视图函数在处理完相关的逻辑后,也需要返回一个响 ...