分享一下 java 处理图像的工具类

本贴最后更新于 3184 天前,其中的信息可能已经水流花落

package com.mss.utils;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

/**

  • 图片处理类

*/
@SuppressWarnings("unused")
public class ImgUtils {

private String IMAGE_TYPE_GIF = "gif";// 图形交换格式 private String IMAGE_TYPE_JPG = "jpg";// 联合照片专家组 private String IMAGE_TYPE_JPEG = "jpeg";// 联合照片专家组 private String IMAGE_TYPE_BMP = "bmp";// 英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式 private String IMAGE_TYPE_PNG = "png";// 可移植网络图形 private String IMAGE_TYPE_PSD = "psd";// Photoshop的专用格式Photoshop /** * 按比例缩放图片 * * * @date 2016年11月21日 * @param srcImageFile 文件路径 * @param result 文件存放路径 * @param scale 放大或缩小倍数 * @param flag true:放大,false:缩小 * void */ public void scale(String srcImageFile, String result, int scale, boolean flag) { try { BufferedImage src = ImageIO.read(new File(srcImageFile)); // 读入文件 int width = src.getWidth(); // 得到源图宽 int height = src.getHeight(); // 得到源图长 if (flag) {// 放大 width = width * scale; height = height * scale; } else {// 缩小 width = width / scale; height = height / scale; } Image image = src.getScaledInstance(width, height,Image.SCALE_DEFAULT); BufferedImage tag = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); // 绘制缩小后的图 g.dispose(); ImageIO.write(tag, "JPEG", new File(result));// 输出到文件流 } catch (IOException e) { e.printStackTrace(); } } /** * * 根据宽高缩放 * * @date 2016年11月21日 * @param srcImageFile 文件路径 * @param result 存放文件路径 * @param height 缩放高度 * @param width 缩放宽度 * @param bb 是否缩放 * void */ @SuppressWarnings("static-access") public void scale2(String srcImageFile, String result, int height, int width, boolean bb) { try { double ratio = 0.0; // 缩放比例 File f = new File(srcImageFile); BufferedImage bi = ImageIO.read(f); Image itemp = bi.getScaledInstance(width, height, bi.SCALE_SMOOTH); // 计算比例 if ((bi.getHeight() > height) || (bi.getWidth() > width)) { if (bi.getHeight() > bi.getWidth()) { ratio = (new Integer(height)).doubleValue() / bi.getHeight(); } else { ratio = (new Integer(width)).doubleValue() / bi.getWidth(); } AffineTransformOp op = new AffineTransformOp(AffineTransform .getScaleInstance(ratio, ratio), null); itemp = op.filter(bi, null); } if (bb) {//补白 BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.setColor(Color.white); g.fillRect(0, 0, width, height); if (width == itemp.getWidth(null)) g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,itemp.getWidth(null), itemp.getHeight(null), Color.white, null); else g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,itemp.getWidth(null), itemp.getHeight(null), Color.white, null); g.dispose(); itemp = image; } ImageIO.write((BufferedImage) itemp, "JPEG", new File(result)); } catch (IOException e) { e.printStackTrace(); } } /** * * 按指定起点坐标和宽高 进行切割 * 注意 y+height!= 图片本身的高度,否则会以补白填充。 * 坐标0,0 是以坐上角开始 * @date 2016年11月21日 * @param srcImageFile * @param result * @param x * @param y * @param width * @param height * void */ public void cut(String srcImageFile, String result, int x, int y, int width, int height) { try { // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > 0 && srcHeight > 0) { Image image = bi.getScaledInstance(srcWidth, srcHeight,Image.SCALE_DEFAULT); // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) ImageFilter cropFilter = new CropImageFilter(x, y, width, height); Image img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(),cropFilter)); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(result)); } } catch (Exception e) { e.printStackTrace(); } } /** * * 指定切片的行数和列数 * * @date 2016年11月21日 * @param srcImageFile * @param descDir * @param rows * @param cols * void */ public void cut2(String srcImageFile, String descDir, int rows, int cols) { try { if(rows<=0||rows>20) rows = 2; // 切片行数 if(cols<=0||cols>20) cols = 2; // 切片列数 // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > 0 && srcHeight > 0) { Image img; ImageFilter cropFilter; Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); int destWidth = srcWidth; // 每张切片的宽度 int destHeight = srcHeight; // 每张切片的高度 // 计算切片的宽度和高度 if (srcWidth % cols == 0) { destWidth = srcWidth / cols; } else { destWidth = (int) Math.floor(srcWidth / cols) + 1; } if (srcHeight % rows == 0) { destHeight = srcHeight / rows; } else { destHeight = (int) Math.floor(srcWidth / rows) + 1; } // 循环建立切片 // 改进的想法:是否可用多线程加快切割速度 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter(j * destWidth, i * destHeight,destWidth, destHeight); img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(),cropFilter)); BufferedImage tag = new BufferedImage(destWidth,destHeight, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, null); // 绘制缩小后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg")); } } } } catch (Exception e) { e.printStackTrace(); } } /** * * 指定切片的宽度和高度 * * @date 2016年11月21日 * @param srcImageFile * @param descDir * @param destWidth * @param destHeight * void */ public void cut3(String srcImageFile, String descDir, int destWidth, int destHeight) { try { if(destWidth<=0) destWidth = 200; // 切片宽度 if(destHeight<=0) destHeight = 150; // 切片高度 // 读取源图像 BufferedImage bi = ImageIO.read(new File(srcImageFile)); int srcWidth = bi.getHeight(); // 源图宽度 int srcHeight = bi.getWidth(); // 源图高度 if (srcWidth > destWidth && srcHeight > destHeight) { Image img; ImageFilter cropFilter; Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT); int cols = 0; // 切片横向数量 int rows = 0; // 切片纵向数量 // 计算切片的横向和纵向数量 if (srcWidth % destWidth == 0) { cols = srcWidth / destWidth; } else { cols = (int) Math.floor(srcWidth / destWidth) + 1; } if (srcHeight % destHeight == 0) { rows = srcHeight / destHeight; } else { rows = (int) Math.floor(srcHeight / destHeight) + 1; } // 循环建立切片 // 改进的想法:是否可用多线程加快切割速度 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { // 四个参数分别为图像起点坐标和宽高 // 即: CropImageFilter(int x,int y,int width,int height) cropFilter = new CropImageFilter(j * destWidth, i * destHeight,destWidth, destHeight); img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(),cropFilter)); BufferedImage tag = new BufferedImage(destWidth,destHeight, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(img, 0, 0, null); // 绘制缩小后的图 g.dispose(); // 输出为文件 ImageIO.write(tag, "JPEG", new File(descDir + "_r" + i + "_c" + j + ".jpg")); } } } } catch (Exception e) { e.printStackTrace(); } } /** * * 图像类型转换 * * @date 2016年11月21日 * @param srcImageFile 文件路径 * @param formatName 转换格式 * @param destImageFile 文件存储路径 * void */ public void convert(String srcImageFile, String formatName, String destImageFile) { try { File f = new File(srcImageFile); f.canRead(); f.canWrite(); BufferedImage src = ImageIO.read(f); ImageIO.write(src, formatName, new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } /** * * 彩色图片转黑白 * * @date 2016年11月21日 * @param srcImageFile * @param destImageFile * void */ public void gray(String srcImageFile, String destImageFile) { try { BufferedImage src = ImageIO.read(new File(srcImageFile)); ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); ColorConvertOp op = new ColorConvertOp(cs, null); src = op.filter(src, null); ImageIO.write(src, "JPEG", new File(destImageFile)); } catch (IOException e) { e.printStackTrace(); } } /** * * 给图片添加文字水印 * * @date 2016年11月21日 * @param pressText 水印文字 * @param srcImageFile 文件路径 * @param destImageFile 文件保存路径 * @param fontName 字体名称 例如:宋体 * @param fontStyle 字体风格 * @param color 字体颜色 * @param fontSize 字体大小 * @param x 文字的起始坐标 * @param y * @param alpha 文字透明度 * void */ public void pressText(String pressText, String srcImageFile, String destImageFile, String fontName, int fontStyle, Color color, int fontSize,int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int width = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, width, height, null); g.setColor(color); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha)); // 在指定坐标绘制水印文字 g.drawString(pressText, (width - (getLength(pressText) * fontSize))/ 2 + x, (height - fontSize) / 2 + y); g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile));// 输出到文件流 } catch (Exception e) { e.printStackTrace(); } } /** * * * * @date 2016年11月21日 * @param pressText 水印文字 * @param srcImageFile 文件路径 * @param destImageFile 文件保存路径 * @param fontName 字体名称 例如:宋体 * @param fontStyle 字体风格 * @param color 字体颜色 * @param fontSize 字体大小 * @param x 文字的起始坐标 * @param y * @param alpha 文字透明度 * void */ public void pressText2(String pressText, String srcImageFile,String destImageFile, String fontName, int fontStyle, Color color, int fontSize, int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int width = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, width, height, null); g.setColor(color); g.setFont(new Font(fontName, fontStyle, fontSize)); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha)); // 在指定坐标绘制水印文字 g.drawString(pressText, (width - (getLength(pressText) * fontSize))/ 2 + x, (height - fontSize) / 2 + y); g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } /** * * 给图片添加水印图片 * * @date 2016年11月21日 * @param pressImg 水印文件路径 * @param srcImageFile 原文件路径 * @param destImageFile 存储文件路径 * @param x * @param y * @param alpha 透明度 * void */ public void pressImage(String pressImg, String srcImageFile,String destImageFile, int x, int y, float alpha) { try { File img = new File(srcImageFile); Image src = ImageIO.read(img); int wideth = src.getWidth(null); int height = src.getHeight(null); BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = image.createGraphics(); g.drawImage(src, 0, 0, wideth, height, null); // 水印文件 Image src_biao = ImageIO.read(new File(pressImg)); int wideth_biao = src_biao.getWidth(null); int height_biao = src_biao.getHeight(null); g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); g.drawImage(src_biao, (wideth - wideth_biao) / 2, (height - height_biao) / 2, wideth_biao, height_biao, null); // 水印文件结束 g.dispose(); ImageIO.write((BufferedImage) image, "JPEG", new File(destImageFile)); } catch (Exception e) { e.printStackTrace(); } } public static int getLength(String text) { int length = 0; for (int i = 0; i < text.length(); i++) { if (new String(text.charAt(i) + "").getBytes().length > 1) { length += 2; } else { length += 1; } } return length / 2; }

}

打赏 1 积分后可见
1 积分 • 3 打赏
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3203 引用 • 8217 回帖
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 633 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1340 回帖
  • 电影

    这是一个不能说的秘密。

    123 引用 • 608 回帖
  • OkHttp

    OkHttp 是一款 HTTP & HTTP/2 客户端库,专为 Android 和 Java 应用打造。

    16 引用 • 6 回帖 • 94 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 203 关注
  • CodeMirror
    2 引用 • 17 回帖 • 176 关注
  • Excel
    31 引用 • 28 回帖
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖 • 12 关注
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 563 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • Follow
    4 引用 • 12 回帖 • 10 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖 • 1 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 64 关注
  • GraphQL

    GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

    4 引用 • 3 回帖 • 5 关注
  • 互联网

    互联网(Internet),又称网际网络,或音译因特网、英特网。互联网始于 1969 年美国的阿帕网,是网络与网络之间所串连成的庞大网络,这些网络以一组通用的协议相连,形成逻辑上的单一巨大国际网络。

    98 引用 • 367 回帖
  • 浅吟主题

    Jeffrey Chen 制作的思源笔记主题,项目仓库:https://github.com/TCOTC/Whisper

    2 引用 • 32 回帖
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖 • 1 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    10 引用 • 54 回帖 • 184 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 3 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    84 引用 • 414 回帖
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 612 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 33 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 2 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    201 引用 • 120 回帖
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 1 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    118 引用 • 54 回帖 • 11 关注