首先放上最初的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异常的更多相关文章

  1. Java 使用Scanner时的NoSuchElementException异常

    做实验时设计了一个类,在类中的两个不同函数中分别创建了两个Scanner对象,并且在各个函数的结尾使用了close()方法,结果在运行时产生了NoSuchElementException异常. 实验的 ...

  2. 【开源】canvas图像裁剪、压缩、旋转

    前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求. 考虑到已有各轮子的契合度都不高,于是自己重新造了一个轮子. 关于图像裁剪.压缩 在HTML5时代,canvas的功能已经非常强大了,可 ...

  3. canvas图像裁剪、压缩、旋转

    转载于:http://www.cnblogs.com/dailc/p/7843204.html 前言 前段时间遇到了一个移动端对图像进行裁剪.压缩.旋转的需求.考虑到已有各轮子的契合度都不高,于是自己 ...

  4. STM32内存受限情况下摄像头驱动方式与图像裁剪的选择

    1.STM32图像接收接口 使用stm32芯片,128kB RAM,512kB Rom,资源有限,接摄像头采集图像,这种情况下,内存利用制约程序设计. STM32使用DCMI接口读取摄像头,协议如下. ...

  5. PHP图像裁剪为任意大小的图像,图像不变形,不留下空白

    <?php /** * 说明:函数功能是把一个图像裁剪为任意大小的图像,图像不变形 * 参数说明:输入 需要处理图片的 文件名,生成新图片的保存文件名,生成新图片的宽,生成新图片的高 */ fu ...

  6. jQuery的图像裁剪插件Jcrop

    1.最基本使用方法     html代码部分: <img src="demo_files/flowers.gif" id="demoImage"/> ...

  7. HTML canvas图像裁剪

    canvas drawImage方法的图像裁剪理解可能会比较耗时,记录一下,以便供人翻阅! context.drawImage(img,sx,sy,swidth,sheight,x,y,width,h ...

  8. php 图像裁剪(自定义裁剪图片大小)

    <?php /** * 图像裁剪 * @param $title string 原图路径 * @param $content string 需要裁剪的宽 * @param $encode str ...

  9. jQuery Jcrop 图像裁剪

    jQuery Jcrop 图像裁剪 http://code.ciaoca.com/jquery/jcrop/ cropper.js 实现HTML5 裁剪图片并上传(裁剪上传头像.) https://b ...

随机推荐

  1. Raspberry Pi 4B FTP服务器配置

    目录 1. 安装vsftpd并启动 2. 编辑配置文件 3. 重启服务 4. 测试 5. 为Web服务器添加管理员账户,便于通过ftp网站信息 参考资料:树莓派(raspberry pi)学习之安装f ...

  2. 解决oracle服务占用内存过高的问题

    其实这是因为安装Oracle时,为了均衡电脑性能和数据库性能,默认内存大小为物理内存的1/8,自身内存比较大时,oracle所占的内存也会变大.而通常,我们自己的环境并不需要分配那么大的内存来支持Or ...

  3. centos7的网络配置参考

    <鸟哥的Linux私房菜>中的相关介绍和配置:http://linux.vbird.org/linux_basic/0610hardware.php 修改链接(connection)的名字 ...

  4. 服务器 Web服务器 应用服务器区别联系

    服务器: 通俗的讲,我们访问一个网站就相当于访问一个服务器的文件,如果想要通过自己的域名来访问一个网站,首先得将域名部署到你的服务器上,然后就可以通过域名访问到你服务器上的网 页文件.ip地址就相当于 ...

  5. python 简单了解一下 描述器

    1.描述器是什么? 在Python中描述器也被称为描述符, 1)描述器实际上是任何新式类(新式类是继承自 type 或者 object 的类),这种类至少实现了3个特殊的方法__get__, __se ...

  6. android java.util.Date和java.util.sql中Date的区别

    1.将java.util.Date 转换为 java.sql.Date java.sql.Date sd; java.util.Date ud; //initialize the ud such as ...

  7. strace调试跟踪程序运行状态

    查看进程调用和执行状态  :   strace  -f -F  -o debug.log  -p   PID(某个进程ID) 参考资料: http://www.itshouce.com.cn/linu ...

  8. OpenStack Cinder发展动态系列--Austin峰会

    在Mitaka版本,Cinder团队在多个特性和领域取得了重大进展. 本文将做一个简要的介绍:关于在Mitaka版本已经完成的功能和特性,以及讨论在Newton版本将会开发的功能和特性. 1 Cind ...

  9. EasyUI中对datagrid的扩展方法

    以下是给datagrid扩展一个方法的demo 1.给datagrid添加一个属性 $.extend($.fn.datagrid.defaults, { demo: "demo1" ...

  10. 准备openstack基础环境

    在所有的openstack节点上执行 1.配置阿里yum源 yum -y install wget rm -rf /etc/yum.repos.d/* wget -O /etc/yum.repos.d ...