前言
在任何一个综合性网站,我们往往需要上传一些图片资料。但随着高分辨率DC的普及,上传的图片容量会很大,比如300万象素DC出来的文件基本不下600K。为了管理方便,大家可能不愿意每次都用ACDsee修改它,而直接上传到服务器。但是这种做法在客户端看来就没有那么轻松了,对于拨号上网的用户简直是一场恶梦,虽然你可以在图片区域设置wide和high!
上一篇文章中(http://www.csdn.net/Develop/Read_Article.asp?Id=27417)我主要介绍了JPG(JEPG)、GIF、PNG图像的读取及压缩方法,遗憾的是不支持BMP图像。本文一鼓作气、再接再厉,一举解决了这个问题!
程序代码
package BMP;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class BMPReader{
public String Reader(){
Image image; //构造一个目标图
String result=""; //返回结果
try{
FileInputStream fs=new FileInputStream("/test.BMP");
int bflen=14;
byte bf[]=new byte[bflen];
fs.read(bf,0,bflen); //读取14字节BMP文件头
int bilen=40;
byte bi[]=new byte[bilen];
fs.read(bi,0,bilen); //读取40字节BMP信息头
// 获取一些重要数据
int nwidth=(((int)bi[7]&0xff)<<24) //源图宽度
| (((int)bi[6]&0xff)<<16)
| (((int)bi[5]&0xff)<<8)
| (int)bi[4]&0xff;
System.out.println("宽:"+nwidth);
int nheight=(((int)bi[11]&0xff)<<24) //源图高度
| (((int)bi[10]&0xff)<<16)
| (((int)bi[9]&0xff)<<8)
| (int)bi[8]&0xff;
System.out.println("高:"+nheight);
//位数
int nbitcount=(((int)bi[15]&0xff)<<8) | (int)bi[14]&0xff;
System.out.println("位数:"+nbitcount);
//源图大小
int nsizeimage=(((int)bi[23]&0xff)<<24)
| (((int)bi[22]&0xff)<<16)
| (((int)bi[21]&0xff)<<8)
| (int)bi[20]&0xff;
System.out.println("源图大小:"+nsizeimage);
相信代码部分应该没有什么问题吧?通过以下方法,你可以得到更多的信息:
//得到压缩值
intncompression=(((int)bi[19])<<24)
|(((int)bi[18])<<16)
|(((int)bi[17])<<8)
|(int)bi[16];
System.out.println("压缩:" ncompression);
//象素情况
intnxpm=(((int)bi[27]&0xff)<<24)
|(((int)bi[26]&0xff)<<16)
|(((int)bi[25]&0xff)<<8)
|(int)bi[24]&0xff;
System.out.println("X-象素/米:" nxpm);
intnypm=(((int)bi[31]&0xff)<<24)
|(((int)bi[30]&0xff)<<16)
|(((int)bi[29]&0xff)<<8)
|(int)bi[28]&0xff;
System.out.println("Y-象素/米:" nypm);
//颜色使用情况
intnclrused=(((int)bi[35]&0xff)<<24)
|(((int)bi[34]&0xff)<<16)
|(((int)bi[33]&0xff)<<8)
|(int)bi[32]&0xff;
System.out.println("颜色使用数:" nclrused);
intnclrimp=(((int)bi[39]&0xff)<<24)
|(((int)bi[38]&0xff)<<16)
|(((int)bi[37]&0xff)<<8)
|(int)bi[36]&0xff;
System.out.println("颜色显要:" nclrimp);
intnplanes=(((int)bi[13]&0xff)<<8)|(int)bi[12]&0xff;
System.out.println("位面:" nplanes); 软件开发网 www.mscto.com
//信息头中的图像大小
intnbisize=(((int)bi[3]&0xff)<<24)
|(((int)bi[2]&0xff)<<16)
|(((int)bi[1]&0xff)<<8)
|(int)bi[0]&0xff;
System.out.println("BMP信息头大小:" nbisize); 软件开发网 www.mscto.com
//文件大小及种类
intnsize=(((int)bf[5]&0xff)<<24)
|(((int)bf[4]&0xff)<<16)
|(((int)bf[3]&0xff)<<8)
|(int)bf[2]&0xff;
System.out.println("文件种类:" (char)bf[0] (char)bf[1]);
System.out.println("文件大小:" nsize);
后记
可以通过变量nbitcount来判断是否是8位位图并作出相应处理。限于目前24位位图应用较为广泛,所以没有写出相应代码,如有需要可查阅JeffWest与JohnD.Mitchell之著作《Howtoread8-and24-bitMicrosoftWindowsbitmapsinJavaapplications》。
在此,我谨慎的表示:因为位图(BMP)没有经过压缩,所以对于源图的容量几乎没有限制,不会出现内存不足的情况。
在写这篇文章时我只进行了9M左右BMP的读取,其实大家有兴趣的话可以利用50M左右的TIF图转换为BMP(几乎还是50M)来做试验。并欢迎上来指正。
联系客服