文章目录

  • 图片读写
    • 小总结
  • 像素操作
  • 属性操作
  • 缩放
  • 格式转换
  • 其他
    • 统一缩放每个像素的值
    • 执行仿射变换
    • 执行卷积
    • 获取支持读取的文件格式
    • 获取支持写入的文件格式
  • 参考

图片读写

import javax.imageio.ImageIO;class Test {public static void main(String[] args) throws IOException {// 从文件中读取BufferedImage image = ImageIO.read(new File("1.jpg"));// 从链接中读取BufferedImage image1 = ImageIO.read(new URL("http://www.example.com/image.jpg"));// 从InputStream中读取,RPC中通过字节流传输图片的时候可能会用到BufferedImage image2 = ImageIO.read(<inputstream>);}
}

import javax.imageio.ImageIO;class Test {public static void main(String[] args) throws IOException {BufferedImage image = ImageIO.read(new File("1.jpg"));// 将图片内容输出到StreamImageIO.write(image, "jpg", <outoutStream>);// 将图片写入文件ImageIO.write(image, "jpg", new File("out.jpg"));}
}

小总结

使用import javax.imageio.ImageIO;库,这里面封装了很多对图像读写的基础函数。类结构如下:

像素操作

主要涉及到两个函数

  • BufferedImage.getRGB()
  • BufferedImage.setRGB()

找一个经典的通过Mask来融合背景的例子来说明,备注:没有使用png图片,Alpha通道没有数据

可以直接运行

import lombok.Builder;
import lombok.extern.slf4j.Slf4j;import java.awt.image.BufferedImage;/*** @author pengjian05*/
@Slf4j
@Builder
public class CharacterMixer {/*** 前景图*/private BufferedImage frontImage;/*** mask:表示前景图的透明度,纯白为全透明*/private BufferedImage mask;/*** 背景图*/private BufferedImage backImage;BufferedImage mix() throws UnsupportedOperationException {if (!ImageSize.equalsMulti(frontImage, mask, backImage)) {throw new UnsupportedOperationException(String.format("images size should equal! front/mask/back = %s/%s/%s",new ImageSize(frontImage),new ImageSize(mask),new ImageSize(backImage)));}return mixBackground();}// region private methods/*** @param x* @param y* @return*/private int calInEachPixel(int x, int y) {var maskPixel = mask.getRGB(x, y);byte maskAlphaChannel = (byte) (maskPixel);int frontPixel = frontImage.getRGB(x, y);int backPixel = backImage.getRGB(x, y);if (Byte.toUnsignedInt(maskAlphaChannel) == (Byte.MAX_VALUE - Byte.MIN_VALUE)) {return frontPixel;} else if (Byte.toUnsignedInt(maskAlphaChannel) == 0) {return backPixel;}byte[] frontBytes = toByteArray(frontPixel);byte[] backBytes = toByteArray(backPixel);byte[] newByte = new byte[4];newByte[0] = (byte) Byte.toUnsignedInt((byte) (Byte.MAX_VALUE - Byte.MIN_VALUE));newByte[1] = calInEachByte(frontBytes[1], backBytes[1], maskAlphaChannel);newByte[2] = calInEachByte(frontBytes[2], backBytes[2], maskAlphaChannel);newByte[3] = calInEachByte(frontBytes[3], backBytes[3], maskAlphaChannel);return fromByteArray(newByte);}/*** 将背景图格式化成没有透明度的rgb图片* <p>* 1. 提取mask中的灰度作为透明度* 2. 针对前景图和背景图每一个通道都计算一下权重(mask本质就是前景透明度所占比重)* 3. 输出*/private BufferedImage mixBackground() {var begin = System.currentTimeMillis();BufferedImage out = new BufferedImage(frontImage.getWidth(),frontImage.getHeight(),BufferedImage.TYPE_3BYTE_BGR);for (int i = 0; i < out.getWidth(); i++) {for (int j = 0; j < out.getHeight(); j++) {out.setRGB(i, j, calInEachPixel(i, j));}}log.info("mix background cost {}ms", System.currentTimeMillis() - begin);return out;}/*** @param front* @param back* @param weight* @return*/private byte calInEachByte(byte front, byte back, byte weight) {float frontWeight = (float) ((float) (Byte.toUnsignedInt(weight)) / 255.0);float backWeight = 1 - frontWeight;return (byte) ((Byte.toUnsignedInt(front)) * frontWeight+ (Byte.toUnsignedInt(back)) * backWeight);}/*** @param bytes* @return* @throws RuntimeException*/public static int fromByteArray(byte[] bytes) throws RuntimeException {if (bytes.length < 4) {throw new RuntimeException(String.format("array too small: %s < %s", bytes.length, 4));}return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3]);}/*** @param b1* @param b2* @param b3* @param b4* @return*/public static int fromBytes(byte b1, byte b2, byte b3, byte b4) {return b1 << 24 | (b2 & 255) << 16 | (b3 & 255) << 8 | b4 & 255;}/*** @param value* @return*/public static byte[] toByteArray(int value) {return new byte[]{(byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value};}// endregion
}

属性操作

import javax.imageio.ImageIO;class Test {public static void main(String[] args) throws IOException {// 从文件中读取BufferedImage image = ImageIO.read(new File("1.jpg"));System.out.println(image.getHeight());System.out.println(image.getWidth());System.out.println(image.getType());   // 内部规定的颜色类型System.out.println(image.getTransparency());   // 获取透明类型,分为(不透明,bit透明(某个像素是透明或不透明两种),透明)System.out.println(image.getColorModel());}
}

缩放

private BufferedImage resizeImage(BufferedImage image, ImageSize target) {BufferedImage resizedImage = new BufferedImage(target.getWidth(), target.getHeight(), image.getType());Image originalImage = image.getScaledInstance(target.getWidth(), target.getHeight(), Image.SCALE_DEFAULT);var g = resizedImage.createGraphics();g.drawImage(originalImage, 0, 0, target.getWidth(), target.getHeight(), null);g.dispose();return resizedImage;
}

在Image对象中有多个缩放算法可以选

  • SCALE_DEFAULT
  • SCALE_FAST
  • SCALE_SMOOTH
  • SCALE_REPLICATE
  • SCALE_AREA_AVERAGING

格式转换

转换成Gray图片

private static BufferedImage convertToGray(BufferedImage image) {if (image.getType() == BufferedImage.TYPE_BYTE_GRAY) {return image;}ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);ColorConvertOp op = new ColorConvertOp(cs, null);return op.filter(image, null);
}

其他图片格式转换也可以通过ColorConvertOp支持的颜色空间(ColorSpace)来完成颜色转换,Java Image支持的颜色空间有:

  • CS_sRGB
  • CS_LINEAR_RGB
  • CS_CIEXYZ
  • CS_PYCC
  • CS_GRAY

注:CS=ColorSpace
更多颜色转化细节可以参考ColorConvertOp的接口

其他

统一缩放每个像素的值

RescaleOp通过将每个像素的样本值乘以一个缩放因子,然后加上一个偏移量,此类对源图像中数据进行逐像素重缩放。缩放后的样本值被限制在目标图像中的最小/最大可表示形式。

重缩放操作的伪代码如下:

for each pixel from Source object {for each band/component of the pixel {dstElement = (srcElement*scaleFactor) + offset}
}

关于RescaleOp的详细资料参考:HERE

执行仿射变换

参考:AffineTransformOp

执行卷积

参考:ConvolveOp

获取支持读取的文件格式

ImageIO.getReaderFileSuffixes();

获取支持写入的文件格式

ImageIO.getWriterFileSuffixes();

参考

  1. RasterOp

Java 图片 基础操作相关推荐

  1. Java并发—基础操作

    原文地址:Java多线程看这一篇就足够了(吐血超详细总结) 目录 一.进程与线程 二.Java中线程实现的方式 三.线程的状态变化 四.线程的操作方法 五.同步以及死锁 六.总结 一.进程与线程 进程 ...

  2. Java图片透明化操作

    public class ClearImageHelper { public static BufferedImage cleanImage(BufferedImage bufferedImage)t ...

  3. 简书 java jvm_Java基础:Java虚拟机(JVM)

    当我们第一次学习Java时这些原理上的东西就会被提到,但是很少有真正去学习.今天开始从头过一遍Java,打算从JVM开始. 1. JVM是什么 JVM是Java Virtual Mechine的缩写. ...

  4. JavaのFile类基础操作之问题

    在上一章节,介绍了File类的基础操作,比如文件的创建,文件的删除等等.这一章节,将介绍在File类基础操作中遇到的问题. 1.路径分割符问题 在实际的软件开发与运行过程中,往往都会在Windows环 ...

  5. java jdbc 教程_java JDBC系列教程之JDBC类的简析与JDBC的基础操作

    什么是JDBC? 概念:JAVA Database Connectivity Javas数据库连接,Java语言操作数据库接口,然后由各个数据库厂商去实现这个接口,提供数据库驱动java包,我们可以使 ...

  6. java取模多位数_JAVA大数类—基础操作(加减乘除、取模、四舍五入、设置保留位数)...

    当基础数据类型长度无法满足需求时可以使用大数类 构造方法接受字符串为参数 1 BigInteger bInt = new BigInteger("123123");2 BigDec ...

  7. java使用poi操作word模板,插入图片、段落、表格

    java使用poi操作word插入图片.段落.表格 其他链接 准备工作 创建word模板.docx文件 编写模板格式.xml文件 java上手poi maven依赖 使用到的包 具体应用 对应封装方法 ...

  8. Java图片操作 --- 图片的读取、绘制、缩放、裁剪、保存

    本文链接: http://blog.csdn.net/xietansheng/article/details/78453570 Java Swing 图形界面开发(目录) 1. 读取图片 方法一: 通 ...

  9. java链表需要自己编写么_基于java的链表基础操作

    链表结构是由一个或一个以上再内存上不连续存储的元素结点连接而成的数据结构,链表的每个结点都有两个部分,一个部分是存储的数据,另一部分是指向下一结点的指针,既是下一节点的引用. 首先链表一定有一个头结点 ...

最新文章

  1. ux设计_从UX设计人员的角度来看Microsoft Build 2018
  2. python和java和scala_有没有与python3相当的scala/java收藏。国家
  3. .bash_profile 写入时间格式YYYY-MM-DD HH24:MI:SS 时报错 not a valid identifier
  4. 32 六角oled驱动_Alienware下半年开售55英寸OLED显示器,4K120Hz、95%DCI-P3
  5. java有什么字符串_Java 中操作字符串都有哪些类?它们之间有什么区别
  6. Pytorch中图像预处理相关函数
  7. java源码导入eclipse_spring framework源码下载并导入eclipse
  8. java8新特性_Java8新特性_lambda表达式
  9. 无人驾驶二 卡尔曼滤波与PID控制
  10. arcengine 加载地图不显示_layUi的html页面动态加载的元素不显示
  11. mysql proxy无法连接_客户端无法通过4040端口连接到mysql proxy
  12. spring面向接口编程
  13. 【深度优先搜索】20行代码解决8皇后问题
  14. 数据库系统工程师输给了计算机等级考试二级
  15. java traingdx函数实现_提取伪彩色图像的信息
  16. 普加.大学生广告创意大赛公告
  17. 个人任务管理系统-数据库
  18. 手机注册服务器异常是什么问题,ohho注册不了网络异常
  19. 计算机如何设置保存到桌面,怎么将电脑桌面上的文件设置默认保存到D盘?
  20. 微软构想务实的SOA 押注Oslo计划

热门文章

  1. python元组和列表
  2. 为什么0x7FFFFFFF+0x7FFFFFFF=-2
  3. 可调电源LM317 的内部原理 - 特殊的电压跟随器
  4. c语言邻接表,C++数据结构之实现邻接表
  5. Win8.1以及win10以上系统 安装msi文件方法
  6. amd 5600g 主机运行ubuntu桌面浏览器崩溃故障初探
  7. CISP-PTE选择题整理(二)
  8. lorawan的工作原理_LoRaWAN中继器技术原理
  9. (纪中)1347. 环中环【DP】
  10. 数据结构题集c语言版第七章答案,数据结构题集(C语言版)答案 - 严蔚敏编著...