BufferedImage 学习

本文详细介绍了BufferedImage类,它是Java中用于处理图像的重要类。BufferedImage具有图像缓冲区,便于进行各种图像操作,如大小调整、灰度转换和透明度设置。文章探讨了BufferedImage的继承结构、组成,包括Raster和ColorModel的角色,以及如何存储和操作像素。此外,还讲解了不同类型的ColorModel,如DirectColorModel和IndexColorModel。最后,概述了BufferedImage的常见操作,包括加载、保存图像以及如何实现图像拼接。
摘要由CSDN通过智能技术生成

一、BufferedImage介绍

image是一个抽象类,BufferedImage是其实现类,是一个带缓冲区图像类,主要作用是将一幅图片加载到内存中(BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便地操作这个图片),提供获得绘图对象、图像缩放、选择图像平滑度等功能,通常用来做图片大小变换、图片变灰、设置透明不透明等。

二、BufferedImage继承关系

在这里插入图片描述

三、BufferedImage的组成

BufferedImage对象中最重要的两个组件是Raster与ColorModel,分别用于存储图像的像素数据和颜色数据。

图像像素的存储

图像的是以像素的形式存储在计算机中的,而像素在计算机中又以二进制表示。像素的存储空间取决于像素深度。

像素深度是指存储每个像素所用的位数,也用它来度量图像的分辨率。像素深度决定彩色图像的每个像素可能有的颜色数,或者确定灰度图像的每个像素可能有的灰度级数。如果只有两种颜色黑和白,一个像素用二进制的0或1表示。如果颜色是8位灰度图像,每个像素用一个8位二进制表示。在RGB模式中,一个像素相当于3个字节。

Raster对象的作用与像素存储

BufferedImage对象使用Raster来存储像素数组。Raster对象自己使用两个对象来存储像素,一个是DataBuffer,另一个是SampleModel。DataBuffer为Raster存储像素,SampleModel描述如何在DataBuffer定位给定样本值。

BufferedImage支持从Raster对象中获取任意位置(x,y)点的像素值p(x,y)

image.getRaster().getDataElements(x,y,width,height,pixels)

x,y表示开始的像素点,width和height表示像素数据的宽度和高度,pixels数组用来存放获取到的像素数据,image是一个BufferedImage的实例化引用。

图像类型与ColorModel

ColorModel用来存储像素的颜色值,ColorModel}抽象类封装了将像素值转换为颜色分量的方法(例如,红色、绿色和蓝色)和alpha分量。为了将图像呈现给屏幕、打印机或其他设备中,像素值必须转换为颜色和alpha分量。

java.awt.image包提供了4种颜色模型:

  • PackedColorModel—一个抽象的ColorModel,表现其颜色成分直接嵌入成为该整数像素的数据位的像素值。DirectColorModel是PackedColorModel的子类。
  • DirectColorModel— 一个ColorModel可以表现含有RGB颜色成分,并且其颜色成分直接嵌入作为该像素自身数据位的像素。DirectColorModel模型的观感与X11 TrueColor相似。
  • ComponentColorModel—ColorModel可以处理任意的ColorSpace以及由颜色成分构成的、与ColorSpace相匹配的数组。
  • IndexColorModel—一个ColorModel,所表现的像素值是一个sRGB颜色空间的固定颜色表的索引。

IndexColorModel的构造函数有五个参数:分别为
1)Bits:表示每个像素所占的位数,对RGB来说是8位
2)Size:表示颜色组件数组长度,对应RGB取值范围为0~255,值为256
3)r[]:字节数组r表示颜色组件的RED值数组
4)g[]:字节数组g表示颜色组件的GREEN值数组
5)b[]:字节数组b表示颜色组件的BLUE值数组

四、BufferedImage的操作

Java将一副图片加载到内存中的方法

BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filePath));

远程图片转BufferedImage

/**
     * 远程图片转BufferedImage
     * @param destUrl    远程图片地址
     * @return
     */
    public static BufferedImage getBufferedImageDestUrl(String destUrl) {
        HttpURLConnection conn = null;
        BufferedImage image = null;
        try {
            URL url = new URL(destUrl);
            conn = (HttpURLConnection) url.openConnection();
            if (conn.getResponseCode() == 200) {
                image = ImageIO.read(conn.getInputStream());
                return image;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return image;
    }

写图像文件的代码

File outputfile = new File("saved.png");
ImageIO.write(bufferedImage, "png",outputfile);

创建一个全新的BufferedImage对象,直接调用BufferedImage的构造函数

BufferedImage  bi = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY)
//其中width表示图像的宽度,height表示图像的高度,最后一个参数表示图像字节灰度图像

根据已经存在的BufferedImage对象来创建一个相同的copy体

public BufferedImage createBufferedImage(BufferedImage src){

  ColorModel  cm = src.getColorModel();

  BufferedImage image = new BufferedImage(cm,

      cm.creatCompatibleWritableRaster(

      src.getWidth(),

      src.getHeight()),

      cm.isAlphaPremultiplied(), null);

  return image;

}

实现图片拼接

/**
     * 待合并的两张图必须满足这样的前提,如果水平方向合并,则高度必须相等;如果是垂直方向合并,宽度必须相等。
     * mergeImage方法不做判断,自己判断。      * @param img1 待合并的第一张图
     * @param img2 带合并的第二张图
     * @param isHorizontal 为true时表示水平方向合并,为false时表示垂直方向合并
     * @return 返回合并后的BufferedImage对象
     * @throws IOException
     */
    public static BufferedImage mergeImage(BufferedImage img1,
            BufferedImage img2, boolean isHorizontal) throws IOException {
        int w1 = img1.getWidth();
        int h1 = img1.getHeight();
        int w2 = img2.getWidth();
        int h2 = img2.getHeight();

        // 从图片中读取RGB
        int[] ImageArrayOne = new int[w1 * h1];
        ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行扫描图像中各个像素的RGB到数组中
        int[] ImageArrayTwo = new int[w2 * h2];
        ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);

        // 生成新图片
        BufferedImage DestImage = null;
        if (isHorizontal) { // 水平方向合并
            DestImage = new BufferedImage(w1+w2, h1, BufferedImage.TYPE_INT_RGB);
            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
        } else { // 垂直方向合并
            DestImage = new BufferedImage(w1, h1 + h2, BufferedImage.TYPE_INT_RGB);
            DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 设置上半部分或左半部分的RGB
            DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 设置下半部分的RGB
        }

        return DestImage;
    }
  • 13
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值