通过ImageReader进行图像裁剪时出现NoSuchElementException异常
首先放上最初的Image工具类
package util; import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator; import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream; public class ImageUtil { private ImageUtil() {
} /**
* 裁剪图像
*
* @param x,y 起始点
* @param width,height 宽高
* @param srcpath 被裁减图像路径
* @param subpath 裁剪后保存路径
* @param type 图像类型
* @throws Exception
*/
public static void cut(int x, int y, int width, int height, String srcpath,
String subpath, String type) throws Exception {
FileInputStream is = null;
ImageInputStream iis = null;
try {
// 读取图片文件
is = new FileInputStream(srcpath);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(type);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Rectangle rect = new Rectangle(x, y, width, height);
// 提供一个 BufferedImage,将其用作解码像素数据的目标。
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, type, new File(subpath));
} finally {
if (is != null)
is.close();
if (iis != null)
iis.close();
}
} /**
* 获取图像真实类型
*
* @param path 图像路径
* @return 图像类型
* @throws Exception
*/
public static String getTypeByStream(String path) throws Exception {
FileInputStream is = new FileInputStream(path);
String type = "";
byte[] b = new byte[4];
try {
is.read(b, 0, b.length);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
is.close();
}
}
type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return "jpg";
} else if (type.contains("89504E47")) {
return "png";
} else if (type.contains("47494638")) {
return "gif";
} else if (type.contains("49492A00")) {
return "tif";
} else if (type.contains("424D")) {
return "bmp";
}
return type;
} /**
* byte数组转换成16进制字符串
*
* @param src
* @return
*/
private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
} }
ImageUtil-origin
以前使用ImageReader对jpg图像进行裁剪没有任何异常,这几天接到新的需求,要能对tif图像进行裁剪。原以为只需将传入的type值改为tif即可,但报出了NoSuchElementException异常
java.util.NoSuchElementException
at javax.imageio.spi.FilterIterator.next(ServiceRegistry.java:825)
at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:528)
at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:513)
网上查了半天,各种说法都有,最终找到了问题所在:
在jdk下的src中可以看到jdk自带支持的imageio类型——bmp、gif、jpeg(jpg)、png等,就 是 没 有 tif !!!

所以就有了解决的方向——导入tif的imageio,需要的jar包有3个jai_codec、jai_core、jai_imageio


导入3个jar包后,对工具类进行测试,发现不报异常了,图像也正确切割了
原本到此应该就已经结束了,但是。。。
放到web项目中又报出了NoSuchElementException的异常
于是又是一顿搜索和实验,终于找到了正解——要在迭代器中注册tif的imageio类
IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(new com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriterSpi());
registry.registerServiceProvider(new com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi());
加上这段代码后,在web中终于不会报异常了
所以最后的图片工具类就变成了这样
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator; import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.spi.IIORegistry;
import javax.imageio.stream.ImageInputStream; public class ImageUtil { private ImageUtil() {
} static {
IIORegistry registry = IIORegistry.getDefaultInstance();
registry.registerServiceProvider(new com.sun.media.imageioimpl.plugins.tiff.TIFFImageWriterSpi());
registry.registerServiceProvider(new com.sun.media.imageioimpl.plugins.tiff.TIFFImageReaderSpi());
} /**
* 裁剪图像
*
* @param x,y 起始点
* @param width,height 宽高
* @param srcpath 被裁减图像路径
* @param subpath 裁剪后保存路径
* @param type 图像类型
* @throws Exception
*/
public static void cut(int x, int y, int width, int height, String srcpath,
String subpath, String type) throws Exception {
FileInputStream is = null;
ImageInputStream iis = null;
try {
// 读取图片文件
is = new FileInputStream(srcpath);
Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(type);
ImageReader reader = it.next();
// 获取图片流
iis = ImageIO.createImageInputStream(is);
reader.setInput(iis, true);
ImageReadParam param = reader.getDefaultReadParam();
Rectangle rect = new Rectangle(x, y, width, height);
// 提供一个 BufferedImage,将其用作解码像素数据的目标。
param.setSourceRegion(rect);
BufferedImage bi = reader.read(0, param);
ImageIO.write(bi, type, new File(subpath));
} finally {
if (is != null)
is.close();
if (iis != null)
iis.close();
}
} /**
* 获取图像真实类型
*
* @param path 图像路径
* @return 图像类型
* @throws Exception
*/
public static String getTypeByStream(String path) throws Exception {
FileInputStream is = new FileInputStream(path);
String type = "";
byte[] b = new byte[4];
try {
is.read(b, 0, b.length);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
is.close();
}
}
type = bytesToHexString(b).toUpperCase();
if (type.contains("FFD8FF")) {
return "jpg";
} else if (type.contains("89504E47")) {
return "png";
} else if (type.contains("47494638")) {
return "gif";
} else if (type.contains("49492A00")) {
return "tif";
} else if (type.contains("424D")) {
return "bmp";
}
return type;
} /**
* byte数组转换成16进制字符串
*
* @param src
* @return
*/
private static String bytesToHexString(byte[] src) {
StringBuilder stringBuilder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xFF;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
stringBuilder.append(0);
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
} }
ImageUtil
和初始的工具类相比没什么太多的变动。。。
最后是3个包的下载地址 https://gitee.com/shizuru/ImageUtil/tree/master
通过ImageReader进行图像裁剪时出现NoSuchElementException异常的更多相关文章
- Java 使用Scanner时的NoSuchElementException异常
做实验时设计了一个类,在类中的两个不同函数中分别创建了两个Scanner对象,并且在各个函数的结尾使用了close()方法,结果在运行时产生了NoSuchElementException异常. 实验的 ...
- 【开源】canvas图像裁剪、压缩、旋转
前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求. 考虑到已有各轮子的契合度都不高,于是自己重新造了一个轮子. 关于图像裁剪.压缩 在HTML5时代,canvas的功能已经非常强大了,可 ...
- canvas图像裁剪、压缩、旋转
转载于:http://www.cnblogs.com/dailc/p/7843204.html 前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求.考虑到已有各轮子的契合度都不高,于是自己 ...
- STM32内存受限情况下摄像头驱动方式与图像裁剪的选择
1.STM32图像接收接口 使用stm32芯片,128kB RAM,512kB Rom,资源有限,接摄像头采集图像,这种情况下,内存利用制约程序设计. STM32使用DCMI接口读取摄像头,协议如下. ...
- PHP图像裁剪为任意大小的图像,图像不变形,不留下空白
<?php /** * 说明:函数功能是把一个图像裁剪为任意大小的图像,图像不变形 * 参数说明:输入 需要处理图片的 文件名,生成新图片的保存文件名,生成新图片的宽,生成新图片的高 */ fu ...
- jQuery的图像裁剪插件Jcrop
1.最基本使用方法 html代码部分: <img src="demo_files/flowers.gif" id="demoImage"/> ...
- HTML canvas图像裁剪
canvas drawImage方法的图像裁剪理解可能会比较耗时,记录一下,以便供人翻阅! context.drawImage(img,sx,sy,swidth,sheight,x,y,width,h ...
- php 图像裁剪(自定义裁剪图片大小)
<?php /** * 图像裁剪 * @param $title string 原图路径 * @param $content string 需要裁剪的宽 * @param $encode str ...
- jQuery Jcrop 图像裁剪
jQuery Jcrop 图像裁剪 http://code.ciaoca.com/jquery/jcrop/ cropper.js 实现HTML5 裁剪图片并上传(裁剪上传头像.) https://b ...
随机推荐
- 关于rsa公钥格式的处理,一行纯内容进行换行格式化
最近在开发百度小程序,他的平台公钥是纯字符串,公钥的内容,没有rsa文件的头(-----BEGIN PUBLIC KEY-----)和尾部分-----END PUBLIC KEY----- 但是 PH ...
- Reconnect due to socket error java.nio.channels.ClosedChannelException
storm整合kafka后出现如下异常: 错误原因:有部分kafka服务器连接不上导致,检查一下是不是每个kafka都能连接到(有的kafka配置使用的是host,记得配置相同的环境) 造成异常代码段 ...
- 查询Oracle正在执行的sql语句及kill被锁的表
查询Oracle正在执行的sql语句及执行该语句的用户SELECT b.sid oracleID, b.username 登录Oracle用户名, b.serial#, spid 操作系统ID, pa ...
- CentOS7.4中配置jdk环境
参考:https://www.linuxidc.com/Linux/2016-09/135556.htm 1.下载jdk 首先创建安装包放置位置 mkdir -p /usr/local/java 然后 ...
- ArcGIS超级工具SPTOOLS-线封闭,点集转面
一.线封闭 操作视频:https://weibo.com/tv/v/HvyvbAxKh?fid=1034:4375207666991674 将末端不闭合线,自动生成闭合的线,效果如下 原始线:末端不闭 ...
- linux下mysql下载安装
1.下载地址 https://www.mysql.com/downloads/ 选择community server 点击DOWLOAD 选择版本,当前选择的5.6版本 点击下载mysql-5.6. ...
- 绿色版plsql安装和安装包
转: 绿色版plsql安装和安装包 2018年08月07日 19:53:15 YoungLee16 阅读数 4890 最近在使用数据库的时候,或多或少的会出现一些问题,下面总结下如何安装ORACL ...
- C++ fill fill_n generate generate_n
#include <iostream>#include <algorithm>#include <vector>#include <list>#incl ...
- JAVA 基础编程练习题40 【程序 40 字符串排序】
40 [程序 40 字符串排序] 题目:字符串排序. package cskaoyan; public class cskaoyan40 { @org.junit.Test public void a ...
- JAVA 基础编程练习题23 【程序 23 求岁数】
23 [程序 23 求岁数] 题目:有 5 个人坐在一起,问第五个人多少岁?他说比第 4 个人大 2 岁.问第 4 个人岁数,他说比第 3 个 人大 2 岁.问第三个人,又说比第 2 人大两岁.问第 ...