项目管理软件破解版:[JAVA]读取BMP图

来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 10:59:55
http://www.tanei.com/thread-845-1-1.html 1 程序功能
1.1 读取24位的bmp格式的图像
1.2 对图像进行过滤,只显示RGB中的一个通道以及显示成灰度图像
1.3 将图像保存为JPG格式的图像
2 实现过程
2.1 读取BMP格式的图像
2.1.1 图像信息类
由于BMP格式的图像前54个字节都是用来存储图像信息,包括图像宽度、高度、大小等等,因此可以构建图像信息类来读取并存储图像的信息。
public class ImageHead
{
private int width;
private int height;
private int bitcount;
private int size;
public ImageHead(FileInputStream stream)
{
try
{
byte bh[] = new byte[bfhead];
byte bi[] = new byte[bfinfo];
stream.read(bh, 0, bfhead);
stream.read(bi, 0, bfinfo);
//图像宽度
width = ( ( (int) bi[7] & 0xff) << 24) //width of source file
| ( ( (int) bi[6] & 0xff) << 16)
| ( ( (int) bi[5] & 0xff) << 8)
| (int) bi[4] & 0xff;
//图像高度
height = ( ( (int) bi[11] & 0xff) << 24) //heigth of source file
| ( ( (int) bi[10] & 0xff) << 16)
| ( ( (int) bi[9] & 0xff) << 8)
| (int) bi[8] & 0xff;
//图像位数
bitcount = ( ( (int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff;
//图像大小
size = ( ( (int) bi[23] & 0xff) << 24)
| ( ( (int) bi[22] & 0xff) << 16)
| ( ( (int) bi[21] & 0xff) << 8)
| (int) bi[20] & 0xff;
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
}
}
复制代码
2.1.2 构建位数组
由于像素使用的字节若不是4的倍数,则会自动扩大,由此产生空白。因此我们需要在一开始计算出空白的大小,即
int blank = ((img.size / img.height) - img.width * 3)/(3 * img.width);
复制代码
由此构建数组如下
byte brgb[] = new byte[ (img.width + blank) * 3 * img.height];
复制代码
2.1.3 读取BMP格式的图像
使用stream.read(brgb, 0, (img.width + blank) * 3 * img.height);读入图像后使用toolkit生成图像:
Toolkit kit = Toolkit.getDefaultToolkit();
image = kit.createImage(new MemoryImageSource(img.width, img.height, data, 0, img.width));
复制代码
2.2 过滤图像,单通道显示
2.2.1  RGBImageFilter类派生
JAVA中存在用于过滤图像的专用类RGBImageFilter,我们只需要对其进行派生即可。
2.2.2 红绿蓝单通道显示
对于每一个像素单元,由三个字节存储RGB三色,还有一个字节用于存储透明度。四个字节的排序为 透明度-红-绿-蓝,由于是16进制并且透明度不改变,因此可以用形如0xffffffff过滤器与色素相与得到指定通道。
红色:0xffff0000
绿色:0xff00ff00
蓝色:0xff0000ff
2.2.3 灰度显示
与单通道显示不同的是,灰度显示本质上是红绿蓝三通道为同一值,从而让灰度存在255阶。
简单的方法是直接选出某一通道,例如红色,覆盖掉其他通道的颜色值从而使得图像显示成灰色。然而这样选取的问题在于,对于一幅红色为0或255的图像,无论蓝色绿色为何,过滤后的图像只会是白色或黑色。
比较好的一种算法是:红色值*0.3+绿色值*0.59+蓝色值*0.11,将得到的值赋予每个通道从而得到灰度值。此种算法的优点在于综合了各个通道,从而避免极端情况。
int gray = (int)(((rgb & 0x00ff0000)>>16)*0.3 + ((rgb & 0x0000ff00)>>8)*0.59 + (rgb & 0x000000ff)*0.11);
2.3 存储为JPG格式
存储为JPG格式我们使用了JAVA的API接口ImageIO实现。由于要使用ImageIO只能将内存中的缓存图像写入文件,因此要先生成缓存图像BufferedImage将图像“画”到其中:
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
复制代码
最后使用ImageIO写入
ImageIO.write(bi, "jpg", imgFile);
复制代码
自己写的ImageIO类
public class MyImageIO implements IImageIO
{
private static int bfhead = 14;
private static int bfinfo = 40;
public class ImageHead
{
private int width;
private int height;
private int bitcount;
private int size;
public ImageHead(FileInputStream stream)
{
try
{
byte bh[] = new byte[bfhead];
byte bi[] = new byte[bfinfo];
stream.read(bh, 0, bfhead);
stream.read(bi, 0, bfinfo);
width = ( ( (int) bi[7] & 0xff) << 24) //width of source file
| ( ( (int) bi[6] & 0xff) << 16)
| ( ( (int) bi[5] & 0xff) << 8)
| (int) bi[4] & 0xff;
height = ( ( (int) bi[11] & 0xff) << 24) //heigth of source file
| ( ( (int) bi[10] & 0xff) << 16)
| ( ( (int) bi[9] & 0xff) << 8)
| (int) bi[8] & 0xff;
bitcount = ( ( (int) bi[15] & 0xff) << 8) | (int) bi[14] & 0xff;
size = ( ( (int) bi[23] & 0xff) << 24)
| ( ( (int) bi[22] & 0xff) << 16)
| ( ( (int) bi[21] & 0xff) << 8)
| (int) bi[20] & 0xff;
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
}
}
public Image myRead(String filePath)
{
try
{
Image image;
FileInputStream stream = new FileInputStream(filePath);
ImageHead img = new ImageHead(stream);
int blank = ((img.size / img.height) - img.width * 3)/(3 * img.width);
int data[] = new int[img.height * img.width];
byte brgb[] = new byte[ (img.width + blank) * 3 * img.height];
if (img.bitcount == 24)
{
stream.read(brgb, 0, (img.width + blank) * 3 * img.height);
int nindex = 0;
for (int j = 0; j < img.height; j++)
{
for (int i = 0; i < img.width; i++)
{
data[img.width * (img.height - j - 1) + i] =
(255 & 0xff) << 24
| ( ( (int) brgb[nindex + 2] & 0xff) << 16)
| ( ( (int) brgb[nindex + 1] & 0xff) << 8)
| (int) brgb[nindex] & 0xff;
nindex += 3;
}
nindex += blank;
}
}
Toolkit kit = Toolkit.getDefaultToolkit();
image = kit.createImage(new MemoryImageSource(img.width, img.height, data, 0, img.width));
return image;
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
return (Image)null;
}
public Image myWrite(Image image, String filePath)
{
try
{
File imgFile = new File(filePath + ".jpg");
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = bi.createGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
ImageIO.write(bi, "jpg", imgFile);
return image;
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
return image;
}
}
复制代码
ImageProcess 图像处理,包括RGB单通道颜色以及灰度
public class ImageProcessor implements IImageProcessor
{
public Image showChanelR(Image sourceImage)
{
RedFilter filter = new RedFilter();
Toolkit kit = Toolkit.getDefaultToolkit();
Image newimg = kit.createImage(new FilteredImageSource(sourceImage.getSource(), filter));
return newimg;
}
public Image showChanelG(Image sourceImage)
{
GreenFilter filter = new GreenFilter();
Toolkit kit = Toolkit.getDefaultToolkit();
Image newimg = kit.createImage(new FilteredImageSource(sourceImage.getSource(), filter));
return newimg;
}
public Image showChanelB(Image sourceImage)
{
BlueFilter filter = new BlueFilter();
Toolkit kit = Toolkit.getDefaultToolkit();
Image newimg = kit.createImage(new FilteredImageSource(sourceImage.getSource(), filter));
return newimg;
}
public Image showGray(Image sourceImage)
{
GrayFilter filter = new GrayFilter();
Toolkit kit = Toolkit.getDefaultToolkit();
Image newimg = kit.createImage(new FilteredImageSource(sourceImage.getSource(), filter));
return newimg;
}
class RedFilter extends RGBImageFilter
{
public RedFilter()
{
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb)
{
return (rgb & 0xffff0000);
}
}
class GreenFilter extends RGBImageFilter
{
public GreenFilter()
{
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb)
{
return (rgb & 0xff00ff00);
}
}
class BlueFilter extends RGBImageFilter
{
public BlueFilter()
{
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb)
{
return (rgb & 0xff0000ff);
}
}
class GrayFilter extends RGBImageFilter
{
public GrayFilter()
{
canFilterIndexColorModel = true;
}
public int filterRGB(int x, int y, int rgb)
{
int gray = (int)(((rgb & 0x00ff0000)>>16)*0.3 + ((rgb & 0x0000ff00)>>8)*0.59 + (rgb & 0x000000ff)*0.11);
return (rgb & 0xff000000)+(gray<<16)+(gray<<8)+gray;
}
}
}
复制代码