熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

高效獲取jpeg圖片的尺寸

2013-11-23 18:49:56  來源: Java核心技術 

  獲取圖片的尺寸有三種方法

  將整個圖片文件加載成 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 方法區中多存放一些類的信息以及方法的信息


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25816.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.