Java不需要加载整张图片而获取图片的大小
转载地址 http://blog.jdk5.com/zh/java-get-image-size-without-loading-the-whole-data/
利用Java类,获取图片的类型,宽度和高度,方法有多种,比如:
- BufferedImage bimg = ImageIO.read(new File("d:\\image\\org.jpg"));
- int width = bimg.getWidth();
- int height = bimg.getHeight();
但这方法将整张图片都加载到了内存,如果那些图片比较大,无疑将增加服务的压力。
下面推荐一个更简单的方法,不需要加载整个图片,从而节省内存空间。
代码如下:
- package com.jiafuwei.java;
- import java.io.ByteArrayInputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- public class SimpleImageInfo {
- private int height;
- private int width;
- private String mimeType;
- public SimpleImageInfo(File file) throws IOException {
- InputStream is = new FileInputStream(file);
- try {
- processStream(is);
- } finally {
- is.close();
- }
- }
- public SimpleImageInfo(InputStream is) throws IOException {
- processStream(is);
- }
- public SimpleImageInfo(byte[] bytes) throws IOException {
- InputStream is = new ByteArrayInputStream(bytes);
- try {
- processStream(is);
- } finally {
- is.close();
- }
- }
- private void processStream(InputStream is) throws IOException {
- int c1 = is.read();
- int c2 = is.read();
- int c3 = is.read();
- mimeType = null;
- width = height = -1;
- if (c1 == 'G' && c2 == 'I' && c3 == 'F') { // GIF
- is.skip(3);
- width = readInt(is,2,false);
- height = readInt(is,2,false);
- mimeType = "image/gif";
- } else if (c1 == 0xFF && c2 == 0xD8) { // JPG
- while (c3 == 255) {
- int marker = is.read();
- int len = readInt(is,2,true);
- if (marker == 192 || marker == 193 || marker == 194) {
- is.skip(1);
- height = readInt(is,2,true);
- width = readInt(is,2,true);
- mimeType = "image/jpeg";
- break;
- }
- is.skip(len - 2);
- c3 = is.read();
- }
- } else if (c1 == 137 && c2 == 80 && c3 == 78) { // PNG
- is.skip(15);
- width = readInt(is,2,true);
- is.skip(2);
- height = readInt(is,2,true);
- mimeType = "image/png";
- } else if (c1 == 66 && c2 == 77) { // BMP
- is.skip(15);
- width = readInt(is,2,false);
- is.skip(2);
- height = readInt(is,2,false);
- mimeType = "image/bmp";
- } else {
- int c4 = is.read();
- if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
- || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) { //TIFF
- boolean bigEndian = c1 == 'M';
- int ifd = 0;
- int entries;
- ifd = readInt(is,4,bigEndian);
- is.skip(ifd - 8);
- entries = readInt(is,2,bigEndian);
- for (int i = 1; i <= entries; i++) {
- int tag = readInt(is,2,bigEndian);
- int fieldType = readInt(is,2,bigEndian);
- int valOffset;
- if ((fieldType == 3 || fieldType == 8)) {
- valOffset = readInt(is,2,bigEndian);
- is.skip(2);
- } else {
- valOffset = readInt(is,4,bigEndian);
- }
- if (tag == 256) {
- width = valOffset;
- } else if (tag == 257) {
- height = valOffset;
- }
- if (width != -1 && height != -1) {
- mimeType = "image/tiff";
- break;
- }
- }
- }
- }
- if (mimeType == null) {
- throw new IOException("Unsupported image type");
- }
- }
- private int readInt(InputStream is, int noOfBytes, boolean bigEndian) throws IOException {
- int ret = 0;
- int sv = bigEndian ? ((noOfBytes - 1) * 8) : 0;
- int cnt = bigEndian ? -8 : 8;
- for(int i=0;i<noOfBytes;i++) {
- ret |= is.read() << sv;
- sv += cnt;
- }
- return ret;
- }
- public int getHeight() {
- return height;
- }
- public void setHeight(int height) {
- this.height = height;
- }
- public int getWidth() {
- return width;
- }
- public void setWidth(int width) {
- this.width = width;
- }
- public String getMimeType() {
- return mimeType;
- }
- public void setMimeType(String mimeType) {
- this.mimeType = mimeType;
- }
- @Override
- public String toString() {
- return "MIME Type : " + mimeType + "\t Width : " + width
- + "\t Height : " + height;
- }
- }
- package com.jiafuwei.java;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- public class Test {
- public static void main(String[] args) {
- try {
- File f = new File("E:\\1.jpg");
- // Getting image data from a InputStream
- FileInputStream b = new FileInputStream(f);
- SimpleImageInfo imageInfo = new SimpleImageInfo(b);
- System.out.println(imageInfo);
- // Getting image data from a file
- imageInfo = new SimpleImageInfo(f);
- System.out.println(imageInfo);
- // Getting image data from a byte array
- byte[] buffer = new byte[1024 * 6];
- InputStream is = new FileInputStream(f);
- while (is.read(buffer) == -1) {}
- is.close();
- imageInfo = new SimpleImageInfo(buffer);
- System.out.println(imageInfo);
- } catch (Exception e) {
- System.out.println(e.getMessage());
- }
- }
- }
Java不需要加载整张图片而获取图片的大小的更多相关文章
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
- Android Bitmap 全面解析(二)加载多张图片的缓存处理
一般少量图片是很少出现OOM异常的,除非单张图片过~大~ 那么就可以用教程一里面的方法了通常应用场景是listview列表加载多张图片,为了提高效率一般要缓存一部分图片,这样方便再次查看时能快速显示~ ...
- jvm系列(一):java类的加载机制
java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...
- Java中类的加载、连接和初始化
Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...
- Java类的加载、链接和初始化
一.Java的类加载机制回顾与总结: 我们知道一个Java类要想运行,必须由jvm将其装载到内存中才能运行,装载的目的就是把Java字节代码转换成JVM中的java.lang.Class类的对象.这样 ...
- java 类的加载,链接,初始化
本篇的话题,讨论Java类的加载.链接和初始化.Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象.一个Java类从字节代码 ...
- java 中类的加载顺序(转)
1.虚拟机在首次加载Java类时,会对静态初始化块.静态成员变量.静态方法进行一次初始化 2.只有在调用new方法时才会创建类的实例 3.类实例创建过程:按照父子继承关系进行初始化,首先执行父类的初始 ...
- 【Java基础】Java类的加载和对象创建流程的详细分析
相信我们在面试Java的时候总会有一些公司要做笔试题目的,而Java类的加载和对象创建流程的知识点也是常见的题目之一.接下来通过实例详细的分析一下. 实例问题 实例代码 Parent类 package ...
- java程序的加载过程
昨天笔试阿里有个求java程序加载过程的题目很是复杂,回来研究了好久才有点明白,整理一下.原题代码如下,判断输出: public class StaticTest { public static in ...
随机推荐
- xml解析之stax
博文引自:http://zangweiren.iteye.com/blog/647334 Java 6.0对XML支持的新特性有许多方面.比如StAX.针对XML-Web服务的Java架构(JAX-W ...
- python——matplotlib图像的基本处理
1.绘制图像中的点和线 from PIL import Image from pylab import * im = array(Image.open('E:\Python\meinv.jpg')) ...
- SVN 的基本用法
克隆远程库 # svn checkout $URL --username=$userName 显示库信息 # svn info 显示库状态 # svn status 将文件纳入版本管理 # svn a ...
- 05,Python网络爬虫之三种数据解析方式
回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据 ...
- mysql 中的基本用法,以及日期的转换
1.mysql int(10) int 类型长度4个字节,大约表示2^32数字,10代表的是显示长度,一般和FILLZERO约束一起使用,如果没有达到该长度,填充02-->000000002 m ...
- SetConsoleCtrlHandler
Excerpt: Registering a Control Handler Function This is an example of the SetConsoleCtrlHandler fu ...
- DataSource的设置
1.Centos和redhat,Fedora等版本无须设置,直接在cloud.cfg指定,默认是EC2 datasource_list: ['ConfigDrive','OpenStack'] 2.u ...
- [OpenCV]Mat类详解
http://blog.csdn.net/yang_xian521/article/details/7107786 Preface Mat:Matrix Mat类可以被看做是opencv中C++版本的 ...
- 原始套接字--icmp相关
icmp请求 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <uni ...
- django之HTTPResponse和JsonResponse详解
HttpResponse对象 Django服务器接收到客户端发送过来的请求后,会将提交上来的这些数据封装成一个HttpRequest对象传给视图函数.那么视图函数在处理完相关的逻辑后,也需要返回一个响 ...