项目管理软件破解版:[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;
}
}
}
复制代码
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;
}
}
}
复制代码
[JAVA]读取BMP图
读取BMP图像的JAVA类
java BMP
如何修复无法读取的光盘(图)
如何修复无法读取的光盘(图)
java
BMP文件格式详解(BMP file format)
BMP文件格式详解(BMP file format)
能够读取人身体信号的"魔镜"(图)
美国公司研发“魔镜” 能读取人身体信号(图)
美国公司研发“魔镜” 能读取人身体信号(图)
BMP图像文件格式
利用ASP读取RSS
读取文件中的坐标
读取txt文件
读取配置文件函数
Sdcard的读取问题
cin读取失败怎么办?
读取指定行数据
“word无法读取1
内存读取错误是怎么回事
vb读取excel内容
在cad中输出成“.bmp”格式文件
无法读取U盘怎么办