当前位置:首页>>软件教程>>新闻内容  
JBuilder设计获取图片属性程序
作者:何凯 发布时间:2003-12-28 16:52:32 | 【字体:

  一、 基本概述

  图片的应用越来越深入到我们的日常生活中, 譬如目前盛行的短信业务和初露头角的彩信业务等。因此,我们很有必要获取图片的字节数、格式、色彩数、宽度和高度等信息,以更好地在手机上达到完美的效果,满足消费者的迫切需要,提高业务的终合竞争力。

  二、 图片相关信息说明

  1、GIF图片

  GIF图片格式标识符为GIF87A/GIF89A两种,但我们一般看到的GIF图片后缀名均为"GIF"。利用UltraEdit软件打开某个GIF图片文件(例如178×42×32 GIF),你将会看到类似如下图(1)的内容(注意要点击那个"H"按钮哟!)。其格式、宽度、高度和色彩数信息位置不变,而且也是连续一起的。其中,蓝色框内的字符集显示图片格式信息,将十六进制的"47"转换为十进制就是"71",即"G"的ASCII码值,其余的依此类推,就将获得"GIF89A",通过这种方式获取图片的格式比直接获取图片的后缀名要可靠的多。因其后缀名用户可随意更改;红色框内每两位分别显示其宽度和高度信息,并从右往左读取,则分别"00B2"和"002A",即十进制为"178"和"42",也就是图片的宽度和高度;绿色部分显示图片的色彩信息,转换十进制之后为"196",然后进行除"8"得余数为"4",最后将其加"1"并作为"2"的幂,最终就是"32",即"2^(196%8+1)=32"。【其它格式图片参上】


图(1)

  2、JPG图片

  JPG图片格式标识符为"JFIF",而且其信息位置不变。但高度、宽度和色彩数信息位置不太确定,但他们是连续一起的。如下两图(2)[例如761×150×16M JPG]和图(3)[例如1984×1384×16M JPG]所示,并且不止这两种情况。现就图(2)作一些补充说明:红色框内每两位分别显示其高度和宽度信息,并从左往右读取,则分别为"0096"和"02F9",即十进制为"150"和"761",也就是图片的高度和宽度;绿色部分显示图片的色彩信息,转换十进制之后为"03",然后进行乘以"8"得"24",最后将其作为"2"的幂,最终就是"16M",即"2^(3*8+1)=16M"。不过,好像JPG图片的色彩数一般都是"16M"?!


图(2)


 图(3)

  注意:为了避免上述多种的情况的发生,从而导致我们处理非常麻烦,本人发现一个小小的技巧。利用Win操作系统自带的画图工具打开"JPG"文件,之后,不需作任何改变,只要保存替换即可。这时一个戏剧性的变化出来了,其高度、宽度和色彩数信息位置都变得跟图(2)类似,即图(4)是由图(3)变化二来的。


图(4)

  3、BMP图片

  BMP图片格式标识符为"BM",但其格式、宽度、高度和色彩数信息位置不变,但宽度、高度和色彩数信息位置是不连续的。如下图(5)[例如352×288×16M BMP]所示。现就图(5)作一些补充说明:红色框内每两位分别显示其宽度和高度信息,并从右往左读取,则分别为"0160"和"0120",即十进制为"352"和"288",也就是图片的宽度和高度;绿色部分显示图片的色彩信息,转换十进制之后为"24",然后将其作为"2"的幂,最终就是"16M",即"2^(24)=16M"。


图(5)

  4、PNG图片

  PNG图片格式标识符为"PNG",但其格式、宽度和高度信息位置不变,但宽度和高度信息位置是不连续的。如下图(6)[例如18×16×16M PNG]所示。由于其跟BMP图片非常相似,故不作重复说明。


图(6)

  三、 源代码及其说明

  源代码由两部分组成,即两个文件组成。其一为"PicsModel.java",主要存储图片的相关信息;其二位"readpic.java",获取图片的相关信息,是本文的重点所在。详细代码如下:

  PicsModel.java代码:

/*****************************************************************
* File name: PicsModel.java
* Create date: 2003-11-18
* Copyright: Copyright (c) 2003 by HEKAI
* @Version: 1.0
* Modify History
* Author Date Description
* hekai 2003-11-18 Create the PicsModel.java
*****************************************************************/
//请用你的相应包名进行替换
package bmptest;

import java.io.Serializable;
public class PicsModel implements Serializable
{
 private String picsExtendName = null;
 private int picsWidth = 0;
 private int picsHeight = 0;
 private String picsColor = null;
 private String picsSize = null;

 public PicsModel()
 {
 }

 public String getpicsExtendName()
 {
  return picsExtendName;
 }
 public void setpicsExtendName(String picsExtendName)
 {
  this.picsExtendName = picsExtendName;
 }

 public int getpicsWidth()
 {
  return picsWidth;
 }
 public void setpicsWidth(int picsWidth)
 {
  this.picsWidth = picsWidth;
 }

 public int getpicsHeight()
 {
  return picsHeight;
 } 
 public void setpicsHeight(int picsHeight)
 {
  this.picsHeight = picsHeight;
 }

 public String getpicsColor()
 {
  return picsColor;
 }
 public void setpicsColor(String picsColor)
 {
  this.picsColor = picsColor;
 }

 public String getpicsSize()
 {
  return picsSize;
 }
 public void setpicsSize(String picsSize)
 {
  this.picsSize = picsSize;
 }
}

readpic.java代码:

/*****************************************************************
* File name: readpic.java
* Create date: 2003-11-18
* Copyright: Copyright (c) 2003 by HEKAI
* @Version: 1.0
* Modify History
* Author Date Description
* hekai 2003-11-18 Create the readpic.java
*****************************************************************/
//请用你的相应包名进行替换
package bmptest;

import java.io.*;
public class readpic
{
 public static void main(String[] args)
 {
  PicsModel model = getFileAttributes("E:/hekai/hk0001.jpg");
  // "E:\\hekai\\hk0001.jpg" 也是可以的
  System.out.println("picextendname is:"+model.getpicsExtendName());
  System.out.println("picwidth is:"+model.getpicsWidth());
  System.out.println("picheight is:"+model.getpicsHeight());
  System.out.println("piccolor:"+model.getpicsColor());
  System.out.println("picsize:"+model.getpicsSize());
 }

 private static PicsModel getFileAttributes(String picpath)
 {
  PicsModel model = null;
  String picextendname;
  picextendname = null;
  byte[] content = null;

  try
  {
   content = readFromFile(picpath);
   int k;
   k = content.length;
   //不想处理的话,请直接获取其字节数
   Integer kk;
   kk = null;
   String picsize;
   picsize = null;
   if (k >= 1024)
   {
    //bigger than fact pic file sizes
    k = k / 1024 + 1;
    kk = new Integer(k);
    picsize = kk.toString() + "K";
   }
   else if (k > 0)
   {
    kk = new Integer(k);
    picsize = kk.toString();
   }
   model = new PicsModel();
   model.setpicsSize(picsize);
  }
  catch( IOException e )
  {
   content = new byte[0];
   e.printStackTrace();
  }

  picextendname = getFileExtendName(content);

  int picwidth,picheight,color;
  String piccolor;
  picwidth = 0;
  picheight = 0;
  color = 0;
  piccolor = null;

  if (picextendname.equals("GIF"))
  {
   //picwidth position
   picwidth = getFileAttribute(content,7,2,picextendname);
   //picheight position
   picheight = getFileAttribute(content,9,2,picextendname);
   //piccolor position
   color = getFileAttribute(content,10,1,picextendname);
   color = color % 8 + 1;
   piccolor = getPicColor(color);
  }
  if (picextendname.equals("JPG"))
  {
   //考虑了两种情况
   picwidth = getFileAttribute(content,166,2,picextendname);
   picheight = getFileAttribute(content,164,2,picextendname);
   color = getFileAttribute(content,167,1,picextendname);
   color = color * 8;
   if ((picwidth == 0 )||(picheight == 0)||(Color > 3))
   {
    picwidth = getFileAttribute(content,197,2,picextendname);
    picheight = getFileAttribute(content,195,2,picextendname);
    color = getFileAttribute(content,198,1,picextendname);
    color = color * 8;
   }
   piccolor = getPicColor(color);
  }
  if (picextendname.equals("BMP"))
  {
   picwidth = getFileAttribute(content,19,2,picextendname);
   picheight = getFileAttribute(content,23,2,picextendname);
   color = getFileAttribute(content,28,1,picextendname);
   piccolor = getPicColor(color);
  }
  if (picextendname.equals("PNG"))
  {
   picwidth = getFileAttribute(content,19,2,picextendname);
   picheight = getFileAttribute(content,23,2,picextendname);
   // usually is "16M"??
   piccolor = "16M";
  }

  model.setpicsExtendName(picextendname);
  model.setpicsWidth(picwidth);
  model.setpicsHeight(picheight);
  model.setpicsColor(piccolor);

  return model;
 }

 private static byte[] readFromFile(String fileName) throws IOException
 {
  PicsModel model = null;
  FileInputStream fin = new FileInputStream(fileName);
  byte [] buf = new byte[fin.available()];
  fin.read(buf);
  fin.close();
  return buf;
 }

 private static String getFileExtendName(byte[] byte1)
 {
  String strFileExtendName;
  strFileExtendName = null;

  //header bytes contains GIF87a or GIF89a?
  if ((byte1[0] == 71)&&(byte1[1] == 73)&&(byte1[2] == 70)&&(byte1[3] == 56)&&((byte1[4] == 55)||(byte1[4] == 57))&&(byte1[5] == 97))
  {
   strFileExtendName = "GIF";
  }
  //header bytes contains JFIF?
  if ((byte1[6] == 74)&&(byte1[7] == 70)&&(byte1[8] == 73)&&(byte1[9] == 70))
  {
   strFileExtendName = "JPG";
  }
  //header bytes contains BM?
  if ((byte1[0] == 66)&&(byte1[1] == 77))
  {
   strFileExtendName = "BMP";
  }
  //header bytes contains PNG?
  if ((byte1[1] == 80)&&(byte1[2] == 78)&&(byte1[3] == 71))
  {
   strFileExtendName = "PNG";
  }

  return strFileExtendName;
 }

 private static int getFileAttribute(byte[] byte2,int n,int m,String fileextendname)
 {
  int j,FileAttributeValue;
  j = 0;
  FileAttributeValue = 0;
  String str,str1;
  str = "";
  str1 = "";

  //如果其大于127,则反之出现少于0,需要进行+256运算
  for (int k = 0; k < m; k ++)
  {
   if (byte2[n-k] < 0)
   {
    j = byte2[n-k];
    j = j + 256;
   }
   else
   {
    j = byte2[n-k];
   }

   str1 = Integer.toHexString(j);
   //转化为16进制,不足位补0
   if (str1.length() < 2)
   {
    str1 = "0" + str1;
   }

   //格式的不同,表达属性的字节也有变化
   if(fileextendname.equalsIgnoreCase("JPG")||fileextendname.equalsIgnoreCase("PNG"))
   {
    str = str1 + str;
   }
   else
   {
    str = str + str1;
   }
  }

  FileAttributeValue = HexToDec(str);
  return FileAttributeValue;
 }

 private static int HexToDec(String cadhex)
 {
  int n, i, j,k,decimal;
  String CADHEX1;
  n = 0;
  i = 0;
  j = 0;
  k = 0;
  decimal = 0;
  CADHEX1 = null;
  n =cadhex.length();
  CADHEX1 = cadhex.trim().toUpperCase();

  while(i < n)
  {
   j = CADHEX1.charAt(i);
   if ((j >= 48) && (j < 65))
   {
    j = j - 48;
   }
   if (j >= 65)
   {
    j = j - 55;
   }
   i = i + 1;

   //16幂运算
   k = 1;
   for (int m = 0; m < (n-i); m ++)
   {
    k = 16 * k;
   }
   decimal = j*k + decimal;
  }

  return decimal;
 }

 private static String getPicColor(int color)
 {
  int k;
  k = 1;
  String piccolor;
  piccolor = null;
  //2幂运算
  for (int m = 0; m < color; m ++)
  {
   k = 2 * k;
  }

  Integer kk;
  kk = null;
  if (k >= 1048576)
  {
   k = k / 1048576;
   kk = new Integer(k);
   piccolor = kk.toString() + "M";
  }
  else if (k >= 1024)
  {
   k = k / 1024;
   kk = new Integer(k);
   piccolor = kk.toString() + "K";
  }
  else if (k > 0)
  {
   kk = new Integer(k);
   piccolor = kk.toString();
  }

  return piccolor;
 }

}

  四、 后记

  以上源代码在Win 2k和Jbuilder 7等环境下正常运行过。由于时间关系,该程序目前只支持GIF(有87A/89A两种格式)、JPG、PNG和BMP格式。另外,对于PNG图片因缺少相关资源文件未作色彩分析。


文章来源:yesky
 放生
 愚爱
 够爱
 触电
 白狐
 葬爱
 光荣
 画心
 火花
 稻香
 小酒窝
 下雨天
 右手边
 安静了
 魔杰座
 你不像她
 边做边爱
 擦肩而过
 我的答铃
 怀念过去
 等一分钟
 放手去爱
 冰河时代
 你的承诺
 自由飞翔
 原谅我一次
 吻的太逼真
 左眼皮跳跳
 做你的爱人
 一定要爱你
 飞向别人的床
 爱上别人的人
 感动天感动地
 心在跳情在烧
 玫瑰花的葬礼
 有没有人告诉你
 即使知道要见面
 爱上你是一个错
 最后一次的温柔
 爱上你是我的错
 怎么会狠心伤害我
 不是因为寂寞才想
 亲爱的那不是爱情
 难道爱一个人有错
 寂寞的时候说爱我