知识大全 高效获取jpeg图片的尺寸

Posted

篇首语:盛年不重来,一日难再晨,及时当勉励,岁月不待人。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 高效获取jpeg图片的尺寸相关的知识,希望对你有一定的参考价值。

  获取图片的尺寸有三种方法

   将整个图片文件加载成 BufferedImage 后获取其尺寸

   用 ImageReader 快捷获取

   即下文所陈述的方式

  做过简陋的测试 效率自 至 逐步递增

  ImageInfo java

  /**

  * @author kodeyang

  */

  public class ImageInfo

  private int height;

  private int width;

  public ImageInfo(int height int width)

  super();

  this height = height;

  this width = width;

  

  public int getWidth()

  return width;

  

  public int getHeight()

  return height;

  

  @Override

  public String toString()

  return height: + height + width: + width;

  

  

  import java io IOException;

  import java io InputStream;

  /**

  * @author yang wei

  *

  */

  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 (in read(seg ) == )

  return null;

  

  // if the first o 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 (in read(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 pression 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 (in read(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 (in read(skip) == )

  return null;

  

  

  // ignore JPEG image precision byte

  if (in read() == )

  return null;

  

  // read JPEG image height and width bytes

  if (in read(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 java io FileInputStream;

  import java io IOException;

  import java io InputStream;

  /**

  * @author yang wei

  *

  */

  public class JpegInfoReaderUsage

  /**

  * @param args

  * @throws IOException

  */

  public static void main(String[] args) throws IOException

  InputStream in = null;

  try

  in = new FileInputStream( d:/images jpg );

  ImageInfo info = JpegInfoReader getImageInfo(in);

  System out println(info);

   finally

  if (in != null)

  in close();

  

  

  

  

  提问

   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 数据的效率是等价的

cha138/Article/program/Java/hx/201311/25816

相关参考