java读取tiff格式图像、像素修改以及格式转换
javatiff_0">java读取tiff图像的踩坑总结:
1.环境:spring boot+maven
2.包:imageio ,jai,codec,metadata;
还有一个从github上面下载的。这几个包都不大好找,等后续补上下载路径。
import javax.imageio.__;
import javax.media.jai.JAI;
import com.sun.media.jai.codec.;
import com.github.jaiimageio.impl.plugins.tiff.*;
主要就是这几个了,下面是接触到的有关代码。
注意:从外部下载的包加载到本地maven仓库需要使用cmd打开输入
mvn install:install-file -DgroupId=com.sun.media -DartifactId=jai_codec -Dversion=1.1.3 -Dpackaging=jar -Dfile=E:\BaiduNetdiskDownload\jai_codec-1.1.3.jar
metadata
tiff_15">首先:metadata,是tiff图像的元数据,下面有两个方式。
1.调用tiffMetadataReader包,此方法比较简单,
引入的包:
import com.drew.imaging.tiff.TiffMetadataReader;
import com.drew.imaging.tiff.TiffProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
//详细过程:
File file = new File("C:/Users/86156/Desktop/Show.tif");
BufferedImage bufferedImage = ImageIO.read(file);
String[] image = ImageIO.getWriterFileSuffixes();
System.out.println(image);
System.out.println(bufferedImage);
try{
Metadata metadata = TiffMetadataReader.readMetadata(file);
//输出元数据信息
System.out.println(metadata);
}catch (tiffProcessingException e){
System.out.println("发生进程异常");
System.out.println(e);
}catch (IOException e) {
System.out.println("发生读取异常");
}
try{
Metadata metadata = TiffMetadataReader.readMetadata(file);
Iterable<Directory> a = metadata.getDirectories();
for(Directory directory : a) {
Iterator<Tag> tag = directory.getTags().iterator();
while (tag.hasNext()) {
System.out.println(tag.next());
}
}
}catch(TiffProcessingException e){
System.out.println("发生异常!");
System.out.println(e);
}
System.out.println("执行完毕");
如果出现读取时是空值:
执行部分结果如下:
包含了tiff图像的长宽和位数即16,这也为后面的大坑做了铺垫。
含有投影坐标:WGS84;
方法二:
- 1
参考链接:https://vimsky.com/examples/detail/java-class-com.drew.imaging.tiff.tiffMetadataReader.html
这个其实自己重写了内置的方法,可以进行修改。
打印效果和上面一样。
tiff_76">tiff图像向其他类型转换(转换后原本的元数据可能会丢失)
如果要转换其他格式只需要更改
ImageCodec.createImageEncoder(“JPEG”, ops, param); //指定输出格式
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.JPEGEncodeParam;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import java.io.*;
/**
* 将 tiff 转换 jpg 格式
* @param filePath
* @return
*/
public static String tiffTuanJPG(String filePath){
String format = filePath.substring(filePath.lastIndexOf(".")+1);
String turnJpgFile = filePath.replace("tiff", "jpg");
if(format.equals("tiff")){
File fileTiff = new File(turnJpgFile);
if(fileTiff.exists()){
System.out.println("该tiff文件已经转换为 JPG 文件:"+turnJpgFile);
return turnJpgFile;
}
RenderedOp rd = JAI.create("fileload", filePath);//读取iff文件
OutputStream ops = null;
try {
ops = new FileOutputStream(turnJpgFile);
//文件存储输出流
JPEGEncodeParam param = new JPEGEncodeParam();
ImageEncoder image = ImageCodec.createImageEncoder("JPEG", ops, param); //指定输出格式
image.encode(rd);
//解析输出流进行输出
ops.close();
System.out.println("tiff转换jpg成功:"+filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return turnJpgFile;
}
注意:传参时需要写入main内
String filePath = "E:/eeee/eee/aod.tiff";
String qq = tiffTuanJPG(filePath);
System.out.println(qq);
- 1
- 2
- 3
方法二resizebyaspect( , , );
可以重新调整大小
private static BufferedImage resizebyaspect(BufferedImage img, int height, int width) {
int ori_width = img.getWidth();
int ori_height = img.getHeight();
float ratio_w = (float)width/ori_width;
float ratio_h = (float)height/ori_height;
int new_width = (ratio_w < ratio_h) ? width : (int)(ratio_h * ori_width);
int new_height = (ratio_h < ratio_w) ? height : (int)(ratio_w * ori_height);
System.out.println(new_width);
System.out.println(new_height);
Image tmp = img.getScaledInstance(new_width, new_height, Image.SCALE_SMOOTH);
BufferedImage bufferedImage = new BufferedImage(new_width, new_height, BufferedImage.TYPE_BYTE_GRAY);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
System.out.println("转换成功");
return bufferedImage;
}
调用:
File input = new File("E:/aod.tiff");
BufferedImage image = ImageIO.read(input);
BufferedImage resized = resizebyaspect(image,230,238);
File output = new File("E:/挑战杯/市数据/保定/aod.jpg");
ImageIO.write(resized, "jpg", output);
转换后对比
tiff_164">3.读取tiff图像的像素值:
这部分自始自终是最令我头痛的了,数组越界。
废话不多说直接上图:
但单个读取时,不会有报错。可能是颜色模型的原因。
因此我尝试着将一个普通的jpg转换成tiff格式后,再次调用该方法却没有报错。
转换格式链接:https://www.aconvert.com/cn/image/tiff-to-png/
代码太多了,放到最后了
获取单个像素点的rgb值
System.out.println(img.getRGB(155, 88));
jpg转tiff后读取rgb值运行结果如下:
-2185377是单个像素点
这个运行结果是jpg转换成tiff的读取结果。但转换过后元数据会有所丢失。
所以很是让人抓狂,16位的图。
虽然至此仍不知该怎么去解决,但是通过此次的自我摸索也获得了很多知识,希望此次能够为正处于这个阶段的同志能够少走一些弯路,另外由衷感谢以上各位提供的开源代码。感谢!
import javax.media.jai.JAI;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.FileImageOutputStream;
import javax.media.jai.operator.TransposeDescriptor;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Hashtable;
import java.util.NoSuchElementException;
import java.util.Vector;
//使用java库对tiff文件进行操作
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.RenderedImage;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.*;
import javax.media.jai.ColorCube;
import javax.media.jai.ImageLayout;
import javax.media.jai.Interpolation;
import javax.media.jai.KernelJAI;
import javax.media.jai.LookupTableJAI;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.ImageEncoder;
import com.sun.media.jai.codec.PNGEncodeParam;
import com.sun.media.jai.codec.TIFFEncodeParam;
import com.sun.media.jai.codec.TIFFField;
import com.sun.media.jai.codecimpl.TIFFImageDecoder;
public class tiff {
public static void main(String[] args) throws IOException {
ImageReader reader = null;
FileImageInputStream fis = null;
//C:\Users\86156\Desktop\aod.tiff
//E:\保定/aod.tiff
File file = new File("C:\\Users\\86156\\Desktop\\aod.tiff");
Object[] src = readtiff(file)