通过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 ...
随机推荐
- POJ 2486 Apple Tree ——(树型DP)
题意是给出一棵树,每个点都有一个权值,从1开始,最多走k步,问能够经过的所有的点的权值和最大是多少(每个点的权值只能被累加一次). 考虑到一个点可以经过多次,设dp状态为dp[i][j][k],i表示 ...
- Notepad++编辑.sh文件
使用记事本创建创建test.txt文件,修改后缀名为sh后,再文件里写以下内容: #!/bin/bash echo "hello world" 这样的文件再linux里是无法执行的 ...
- 常见的RuntimeException
一般面试中java Exception(runtimeException )是必会被问到的问题常见的异常列出四五种,是基本要求.更多的....需要注意积累了 常见的几种如下: NullPointerE ...
- 走进JavaWeb技术世界4:Servlet 工作原理详解
从本篇开始,正式进入Java核心技术内容的学习,首先介绍的就是Java web应用的核心规范servlet 转自:https://www.ibm.com/developerworks/cn/java/ ...
- ajax与HTML5 history API实现无刷新跳转
一.ajax载入与浏览器历史的前进与后退 ajax可以实现页面的无刷新操作,但是无法前进与后退,淡出使用Ajax不利于SEO.如今,HTML5让事情变得简单.当执行ajax操作时,往浏览器histor ...
- 第11组 Beta版本演示
第11组 Beta版本演示 组长博客链接 https://www.cnblogs.com/xxylac/p/12039948.html 本组成员(不知道叫什么团队) 031702635 陈郑铧(组 ...
- C++ list 查找
#include <iostream>#include <list>#include <algorithm> using namespace std; int ma ...
- git撤销某次提交
1.查询提交记录.进入目录,查看某人在此目录下的commit: panxi@ww-bj-panxi MINGW64 [path]/Business (feature/v2.3) $ git log f ...
- 获取当前运行的exe路径
void GetAppPath(CString& path) { TCHAR str[] = {}; GetModuleFileName(NULL,str,); wchar_t *pszPos ...
- mongodb查询修改
//查 public StatisticsSchoolPracticeView findByUser(String userId,int statOrgType,int inDateType){ Qu ...