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

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

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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8217 回帖
  • Eclipse

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

    76 引用 • 258 回帖 • 624 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • Hprose

    Hprose 是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。

    9 引用 • 17 回帖 • 641 关注
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    70 引用 • 193 回帖 • 408 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 43 关注
  • H2

    H2 是一个开源的嵌入式数据库引擎,采用 Java 语言编写,不受平台的限制,同时 H2 提供了一个十分方便的 web 控制台用于操作和管理数据库内容。H2 还提供兼容模式,可以兼容一些主流的数据库,因此采用 H2 作为开发期的数据库非常方便。

    11 引用 • 54 回帖 • 671 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 635 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 246 回帖 • 1 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 522 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1127 回帖 • 108 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 610 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 519 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 78 关注
  • 自由行
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    16 引用 • 236 回帖 • 242 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    346 引用 • 757 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    188 引用 • 1057 回帖 • 2 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 3 关注
  • AWS
    11 引用 • 28 回帖 • 9 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    291 引用 • 4495 回帖 • 663 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    186 引用 • 1021 回帖
  • 996
    13 引用 • 200 回帖 • 1 关注
  • Outlook
    1 引用 • 5 回帖 • 2 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 2 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖