> 文档中心 > java中文件读写与图像处理

java中文件读写与图像处理


文件处理

如何读取文件

Java对于文件的读取操作,都是InputStream子类来完成的。创建一个名为“test.text”的文本文件,并输入以下内容:

这是一个测试文件第2行第3行这行故意留空  

以下是几个示例,展示了如何使用BufferedReader和FileInputStream读取文件:

一行一行读取

public class FileReadDemo {    public static void main(String[] args) throws IOException {    //创建一个文件对象,文件内容为test.text File file = new File("./test.text"); //利用BufferedReader来读取文件 try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {     String line = null;     while (null != (line = bufferedReader.readLine())) {  System.out.println(line);     } } catch (IOException e) {     e.printStackTrace(); }    } }

每次只读取一行,当文件读完之后会返回一个null,表示文件已经读完,将打开流的操作放在try里面,会自动为我们关闭流。

Java8及其以后的JDK还给我们提供了一种更为简便的方法,叫lambda表达式,关于lambda表达式,会专门写一篇文档,感兴趣的可以先了解一下

 public class FileReadDemo {    public static void main(String[] args) throws IOException { File file = new File("./test.text"); Files.lines(file.toPath()).forEach(System.out::println);    } }

指定大小读取文件

很多情况下我们需要读取文件,但是每次只需要读几个字符,这种情况下我们就可以指定一次读取字符的个数

public class FileReadDemo {    public static void main(String[] args) throws IOException { File file = new File("./test.text"); try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { //每次读取10个字符     char[] chars = new char[10];     //内容读完之后就会返回一个-1的值     while (-1 != bufferedReader.read(chars)){  System.out.println(new String(chars));     } } catch (IOException e) {     e.printStackTrace(); }    } }

一次性读取10个字符,char[] chars = new char[10];可以改变这行代码中的10来调整一次性读取的字符数量

一次性读取整个文件

public class FileReadDemo {    public static void main(String[] args) throws IOException { File file = new File("./test.text"); //file.length返回的文章的字节数 Long length = file.length(); try (FileInputStream f = new FileInputStream(file)) {     byte[] bytes = new byte[length.intValue()];     while (-1 != f.read(bytes)) {  System.out.println(new String(bytes));     } } catch (IOException e) {     e.printStackTrace(); }    } }

file.length()表示文件的字节数,我们将一次性读取的长度定位文件的长度,即可一次性读取出文件的所有内容,这种读取方式适合任何文件类型

如何写文件

写文件一般是由OutputStream子类来实现的。

追加写入

public class FileReadDemo {    public static void main(String[] args) throws IOException { File file = new File("./test.text"); //new FileOutputStream(file,true),true表示以追加的方式写入文件,意味着会把hello world写到文档内容的最后 try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file,true))) {     bufferedOutputStream.write("hello world".getBytes()); } catch (IOException e) {     e.printStackTrace(); }    } }

清空文件内容重新写入

public class FileReadDemo {    public static void main(String[] args) throws IOException { File file = new File("./test.text"); //new FileOutputStream(file),没有指定写的模式将会清空文档内容重新加入 //new FileOutputStream(file,false),false表示清空文档的内容,只写入hello world try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file))) {     bufferedOutputStream.write("hello world".getBytes()); } catch (IOException e) {     e.printStackTrace(); }    }}

清空写入和追加写入取决于FileOutputStream流的模式,通过指定append参数可以控制是追加,还是清空写入

至此,文件的读取和写入,已经介绍完毕了。

图片处理

日常工作中,经常会遇到要批量的给图片加滤镜,加水印,按需求缩放图片等操作,如果不懂编程,可能就需要你用ps一张一张的打开图片,修改图片再保存,大量的重复工作将占用你很多宝贵的时间。如果需要处理的图片量大,即便是加班,也不一定能及时完成工作,且及其容易操作失误导致出错。

好在之前的任务中,我们已经掌握了批量搜索和处理文件的能力,也知道了如何用Java来读写文件,现在我们只需要掌握任意一种图片处理库,就能很方便的用脚本来帮助我们完成今天的任务。

图像缩放

工作中可能经常需要对图片做一些调整大小的操作,这里我们用Java实现一个方法,将图片按照比例缩放至原来的80%,你可以稍微改动一下这个方法,让图片可以任意比例缩放。准备一张图片,并命名为test.png,并将图片放入到项目的根目录中,根目录即为项目文件夹的路径

在这里插入图片描述

 public class ImageDemo {    public static void main(String[] args) throws IOException { //创建一个文件对象 File file = new File("test.png"); try {-     //BufferedImage是Image与图像数据的访问的缓冲器     BufferedImage image = ImageIO.read(file);     int width = image.getWidth();     int height = image.getHeight();     //创建此图像的缩放版本。 返回一个新的Image对象     Image scaledInstance = image.getScaledInstance(Double.valueOf(width * 0.8).intValue(), Double.valueOf(height * 0.8).intValue(), Image.SCALE_DEFAULT);     //确定图像的宽度。 如果宽度未知,则此方法返回-1并稍后通知指定的ImageObserver对象     int swidth = scaledInstance.getWidth(null);     int sheight = scaledInstance.getHeight(null);     BufferedImage newImage = new BufferedImage(swidth, sheight,      BufferedImage.TYPE_INT_ARGB);     //Graphics对象封装了 Java 支持的基本渲染操作所需的状态信息,可以理解为是一支画笔     Graphics g = newImage.getGraphics();     //从坐标0,0处画一个图像     g.drawImage(scaledInstance, 0, 0, null);     //处理此图形上下文并释放它正在使用的任何系统资源。 调用dispose后无法使用Graphics对象。     g.dispose();     //将新的图片信息写入scaled.png     ImageIO.write(newImage, "png", new File("scaled.png")); } catch (IOException ioException) {     ioException.printStackTrace(); }    } }

图像滤镜

图像滤镜是图像处理中经常需要用到的操作,比如美颜中的磨皮操作就能让人肤白貌美,这个磨皮就用到了模糊滤镜;把彩色照片转化成黑白照片或者老旧照片就需要用到颜色滤镜,如果你对位图的的数据编码方式非常熟悉,你可以自己利用PIL创造特定的滤镜。(比较有难度,通常大部分开发者都不会自己去创建滤镜)

Java有很多开源工具给我们提供了对应的功能,因此我们可以直接拿来使用,这里介绍一个Java的图片滤镜处理工具Java Image Filters,官网如下

http://www.jhlabs.com/ip/filters/index.html

这里我们选择InvertFilter反转颜色滤镜,在官网将Filters.jar下载下来并导入到工程中

import com.jhlabs.image.InvertFilter;import javax.imageio.ImageIO;import java.awt.*;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;public class ImageDemo {    public static void main(String[] args) throws IOException { File file = new File("test.png"); BufferedImage sourceImage = ImageIO.read(file); Image scaledInstance = sourceImage.getScaledInstance(sourceImage.getWidth(), sourceImage.getHeight(), Image.SCALE_DEFAULT); BufferedImage newImage = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(),  BufferedImage.TYPE_INT_ARGB); Graphics g = newImage.getGraphics(); g.drawImage(scaledInstance, 0, 0, null); g.dispose(); File desfile = new File("testDes.png"); //反转颜色滤镜 InvertFilter invertFilter = new InvertFilter(); invertFilter.filter(sourceImage, newImage); ImageIO.write(newImage, "png", desfile);    }  }

调用这个方法后,test.png这张图片中所有的颜色都会反转,只需要几行代码,就可以完成这个操作

绘图方法

Java也能完成图片的创建,

这里我们创建一个灰色的图片,上面写一个黄色的hello world

import com.github.javafaker.Faker;import org.apache.poi.xssf.usermodel.XSSFRow;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;import java.util.Locale;import java.util.stream.Collectors;import java.util.stream.Stream;public class ImageDemo {    public static void main(String[] args) throws IOException { //画一个400*400的灰色图片 BufferedImage bufferedImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); Graphics g = bufferedImage.getGraphics(); g.setColor(Color.GRAY); g.fillRect(0, 0, 400, 400); //在上面写上黄色的hello wolrd g.setColor(Color.YELLOW); //设置字体,加粗,大小 Font font = new Font("SimHei", Font.BOLD, 50); g.setFont(font); g.drawString("hello world", 100, 200); g.dispose(); ImageIO.write(bufferedImage, "png", new File("gray.png"));    }  }

另外一个常用的功能就是给图片加水印,用代码也能很方便的实现,这里就将一个黄色的hello world字样放到了图片上

public class ImageDemo {    public static void main(String[] args) throws IOException { BufferedImage bufferedImage = ImageIO.read(new File("test.png")); Graphics g = bufferedImage.getGraphics(); //在上面写上黄色的hello world g.setColor(Color.YELLOW); Font font = new Font("SimHei", Font.BOLD, 50); g.setFont(font); g.drawString("hello world", 100, 200); g.dispose(); ImageIO.write(bufferedImage, "png", new File("watermark.png"));    }  }