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);
        if (src == null)
            System.out.println("读取失败");
        reader = (ImageReader) src[0];
        fis = (FileImageInputStream) src[1];
        System.out.println(reader);
        System.out.println(fis);
        long[] dpiData = new long[]{1, 1};
        BufferedImage img = loadtiff(file, dpiData);
        System.out.println(img.getColorModel());
        if (img == null)
            System.out.println("空值");
        //获取图片的长宽和最小值
        int width = img.getWidth();
        int height = img.getHeight();
        int minx = img.getMinX();
        int miny = img.getMinY();
        int rgb[] = new int[width * height];
        int a[][]=new int[img.getWidth()][img.getHeight()];
        /*for (int i = minx; i < img.getWidth(); i++) {
            for (int j = miny; j < img.getHeight(); j++) {
                    a[i][j] = img.getRGB(i, j);
            }
        }
        for (int i = 0; i < img.getWidth(); i++) {
            for (int j = 0; j < img.getHeight(); j++) {
                System.out.print(a[i][j]);
            }
            System.out.println();
        }*/
        for (int i = minx; i < width; i++) {
            for (int j = miny; j < height; j++) {
                int pixel = img.getRGB(i, j); // 下面三行代码将一个数字转换为RGB数字
                rgb[0] = (pixel & 0xff0000) >> 16;
                rgb[1] = (pixel & 0xff00) >> 8;
                rgb[2] = (pixel & 0xff);
                System.out.print("i=" + i + ",j=" + j + ":(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")");
            }
            System.out.println();
        }
        System.out.println(img.getRGB(155, 88));

        System.out.println("-----------------------------");
        //img.getRGB(0,0,width-1,height-1 , rgb,0,width);

        File pfile = new File("E:/挑战杯/市数据/保定/aod_tiff.png");
        //boolean b = makeDispPage(file,0,pfile);
        //System.out.println(b);


    }

    //读取tiff文件到 ImageReader Object[0]:ImageReader ,Object[1]:FileImageInputStream
    private static Object[] readtiff(File tifFile) {
        ImageReader reader = null;
        FileImageInputStream fis = null;
        Object[] res = null;
        try {
            reader = ImageIO.getImageReadersByFormatName("tiff").next();
            fis = new FileImageInputStream(tifFile);
            reader.setInput(fis);
            res = new Object[]{reader, fis};
        } catch (NoSuchElementException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return res;
    }

    //获取tiff dpi
    public static long[] gettiffDPI(ImageReader reader, int index) {
        long[] dpi = new long[2];
        IIOMetadata meta = null;
        try {
            meta = reader.getImageMetadata(index);
            org.w3c.dom.Node n = meta.getAsTree("javax_imageio_1.0");
            n = n.getFirstChild();

            while (n != null) {

                if (n.getNodeName().equals("Dimension")) {

                    org.w3c.dom.Node n2 = n.getFirstChild();

                    while (n2 != null) {

                        if (n2.getNodeName().equals("HorizontalPixelSize")) {

                            org.w3c.dom.NamedNodeMap nnm = n2.getAttributes();

                            org.w3c.dom.Node n3 = nnm.item(0);

                            float hps = Float.parseFloat(n3.getNodeValue());

                            dpi[0] = Math.round(25.4f / hps);

                        }

                        if (n2.getNodeName().equals("VerticalPixelSize")) {

                            org.w3c.dom.NamedNodeMap nnm = n2.getAttributes();

                            org.w3c.dom.Node n3 = nnm.item(0);

                            float vps = Float.parseFloat(n3.getNodeValue());

                            dpi[1] = Math.round(25.4f / vps);
                        }

                        n2 = n2.getNextSibling();

                    }

                }

                n = n.getNextSibling();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return dpi;
    }


    //读取tiff文件到 BufferedImage
    private static BufferedImage loadtiff(File tifFile, long[] dpiData) {

        ImageReader reader = null;
        FileImageInputStream fis = null;
        BufferedImage res = null;
        try {
            Object[] src = readtiff(tifFile);
            if (src == null) {
                return null;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];
            if (reader != null) {
                int numPages = reader.getNumImages(true);
                if (numPages > 0) {
                    long[] dpiArr = gettiffDPI(reader, 0);
                    dpiData[0] = dpiArr[0];
                    dpiData[1] = dpiArr[1];
                    res = reader.read(0);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.dispose();
            }

            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


        }
        return res;
    }

    /**
     * 从tiff文件生成原始像素大小tiff文件
     *
     * @param ftiff  源tiff文件
     * @param decDir tiff目标路径,目标文件将会以0001.tif,0002.tif...置于此路径下
     * @return true表示成功, false表示失败
     */
    public static boolean makeSingleTif(File fTiff, File decDir) {
        boolean bres = true;
        ImageReader reader = null;
        FileImageInputStream fis = null;
        try {
            reader = ImageIO.getImageReadersByFormatName("tiff").next();
            fis = new FileImageInputStream(fTiff);
            reader.setInput(fis);

            int numPages = reader.getNumImages(true);
            for (int i = 0; i < numPages; i++) {

                long[] dpiData = gettiffDPI(reader, i);
                BufferedImage bi = reader.read(i);

                File tif = new File(decDir.getPath() + File.separator
                        + String.format("%1$04d", i + 1) + ".tif");
                bres = createtiff(tif, new RenderedImage[]{bi}, dpiData, false);

            }

        } catch (Exception e) {
            e.printStackTrace();
            bres = false;

        } finally {

            if (reader != null) {
                reader.dispose();
            }

            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }


        return bres;
    }

    /**
     * 合并多个tiff文件成一个多页tiff文件
     *
     * @param ftiff  目标tiff文件
     * @param tifDir 源tiff文件路径,tiff文件必须以0001.tif,0002.tif...置于此路径下
     * @return true表示成功, false表示失败
     */
    static public boolean mergetiff(File fTiff, File tifDir) {

        boolean bres = true;
        ImageReader reader = null;
        FileImageInputStream fis = null;
        Vector<BufferedImage> biV = new Vector<BufferedImage>();
        File[] fs = tifDir.listFiles();
        long[] dpi = null;
        for (File f : fs) {
            String fileName = f.getName();
            if (!fileName.endsWith(".tif")) {
                continue;
            }
            try {
                reader = ImageIO.getImageReadersByFormatName("tiff").next();
                fis = new FileImageInputStream(f);
                reader.setInput(fis);
                biV.add(reader.read(0));
                if (dpi == null) {
                    dpi = gettiffDPI(reader, 0);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (reader != null) {
                    reader.dispose();
                }

                if (fis != null) {
                    try {
                        fis.flush();
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

        RenderedImage[] biArr = new RenderedImage[biV.size()];
        for (int i = 0; i < biArr.length; i++) {
            biArr[i] = biV.get(i);
        }

        bres = createtiff(fTiff, biArr, dpi, false);


        return bres;
    }

    //获取tiff文件的页数
    public static int gettiffPages(File tifFile) {
        ImageReader reader = null;
        FileImageInputStream fis = null;
        int numpages = 0;
        try {
            Object[] src = readtiff(tifFile);
            if (src == null) {
                return 0;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];
            if (reader != null) {
                numpages = reader.getNumImages(true);
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {

            if (reader != null) {
                reader.dispose();
            }

            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


        }
        return numpages;
    }


    /**
     * 生成tiff原始dpi的png
     *
     * @param ftiff   用于生成文件的tif文件
     * @param decFile 目标png
     * @param tifIdx  tif文件页码索引,从0开始
     */
    public static void makePrintPngFromTifByScal(File fTiff, File decFile, int tifIdx) {

        long d = System.currentTimeMillis();
        FileOutputStream os = null;
        ImageReader reader = null;

        FileImageInputStream fis = null;
        try {

            Object[] src = readtiff(fTiff);
            if (src == null) {
                return;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];


            if (reader != null) {
                int numPages = reader.getNumImages(true);
                if (numPages > 0 && tifIdx < numPages) {
                    long[] dpiData = gettiffDPI(reader, tifIdx);
                    BufferedImage img = reader.read(tifIdx);


                    double meter2inchRatio = 1d / 0.0254d;
                    int dimX = (int) (dpiData[0] * meter2inchRatio) + 1;
                    int dimY = (int) (dpiData[0] * meter2inchRatio) + 1;

                    int iYScal = (Math.abs(dpiData[0] - dpiData[1]) <= 10) ? 1 : 2;

                    int width = img.getWidth();
                    int height = img.getHeight() * iYScal;


                    //200 * 210 /25.4 ---- 200 * 297 /25.4

                    double whScal = 230.0 / 238.0;
                    double realScal = (double) width / (double) height;


                    int drawPtX = 0;    //图像起始x位置
                    int drawPtY = 0;    //图像起始Y位置
                    int newW = 230;
                    int newH = 238;


                    if (realScal < whScal) {    // 以高度为缩放基准
                        newW = (int) (238.0 * realScal);
                        drawPtX = (230 - newW) / 2;
                    } else {
                        newH = (int) (230 / realScal);
                        drawPtY = (238 - newH) / 2;
                    }

//System.out.println("width=" + width + ", height=" + height + ", newW=" + newW + ", newH=" + newH + ", dimX=" + dimX + ", dimY=" + dimY);
                    BufferedImage decImg = new BufferedImage(230, 238, BufferedImage.TYPE_3BYTE_BGR);
                    Graphics2D g2 = decImg.createGraphics();
                    g2.setColor(Color.white);
                    g2.fillRect(0, 0, 230, 238);

                    g2.drawImage(img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH), drawPtX, drawPtY, null);


                    PNGEncodeParam paramEnc = PNGEncodeParam.getDefaultEncodeParam(decImg);
                    paramEnc.setPhysicalDimension(dimX, dimY, 1);
                    os = new FileOutputStream(decFile);
                    JAI.create("encode", decImg, os, "PNG", paramEnc);
                    os.flush();
                    os.close();

                }


            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (reader != null) {
                reader.dispose();
            }
            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {

                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        System.out.println(("----make print Pngs time----" + (System.currentTimeMillis() - d) + "ms"));

    }


    /**
     * 从tiff文件生成用于显示的一页png
     *
     * @param ftiff   源tiff文件
     * @param pageIdx 页号,从0开始
     * @param dDecPng 目标png文件
     * @return true表示成功, false表示失败
     */
    static public boolean makeDispPage(File fTiff, int pageIdx, File dDecPng) {
        long d = System.currentTimeMillis();

        ImageReader reader = null;
        FileImageInputStream fis = null;
        boolean bres = false;
        try {
            Object[] src = readtiff(fTiff);
            if (src == null) {
                return false;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];
            if (reader != null) {
                int numPages = reader.getNumImages(true);
                if (numPages > 0) {
                    if (pageIdx >= 0 && (pageIdx < numPages)) {
                        long[] dpi = gettiffDPI(reader, pageIdx);
                        if (dpi != null && dpi.length == 2) {
                            if (dpi[0] <= 0)
                                dpi[0] = 1;
                            if (dpi[1] <= 0)
                                dpi[1] = 1;
                            double dXFac = 1 / dpi[0];
                            double dYFac = 1 / dpi[1];
                            BufferedImage img = reader.read(pageIdx);
                            RenderedImage decImg = ScaleImg(img, dXFac, dYFac);
                            ImageIO.write(decImg, "png", dDecPng);
                            bres = true;
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {

            if (reader != null) {
                reader.dispose();
            }

            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


        }
        System.out.println(("----make disp png by IO use time:" + (System.currentTimeMillis() - d) + "ms"));
        return bres;
    }


    /**
     * 从tiff生成缩略图
     *
     * @param ftiff
     * @param decDir
     * @return
     */
    public static boolean makeThumbsFromtiff(File fTiff, File decDir) {
        long d = System.currentTimeMillis();
        int numPages = 0;
        int thumbWidth = 188;
        int thumbHeight = 254;

        ImageReader reader = null;
        FileImageInputStream fis = null;
        boolean bres = true;
        try {
            Object[] src = readtiff(fTiff);
            if (src == null) {
                return false;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];

            if (reader != null) {
                numPages = reader.getNumImages(true);
                if (numPages > 0) {

                    for (int i = 0; i < numPages; i++) {
                        long[] dpiData = gettiffDPI(reader, i);
                        BufferedImage img = reader.read(i);
                        int ht = img.getHeight();
                        int wid = img.getWidth();
                        float fsc = (float) dpiData[0] / (float) dpiData[1];
                        if (Math.abs(fsc - 1.0) > 0.2) {
                            if (fsc < 1) {
                                wid = (int) (wid / fsc);
                            } else {
                                ht = (int) (ht * fsc);
                            }
                        }

                        double realScal = (double) wid / (double) ht;
                        double whScal = (double) thumbWidth / (double) thumbHeight;

                        int newW = thumbWidth;
                        int newH = thumbHeight;

                        if (realScal < whScal) {    // 以高度为缩放基准
                            newW = (int) (thumbHeight * realScal);
                        } else {
                            newH = (int) (thumbWidth / realScal);
                        }
                        int x = (thumbWidth - newW) / 2;
                        int y = (thumbHeight - newH) / 2;

                        System.out.println(newW + "," + newH + "," + x + "," + y);
                        BufferedImage decImg = new BufferedImage(thumbWidth,
                                thumbHeight, BufferedImage.TYPE_3BYTE_BGR);
                        Graphics2D g2 = (Graphics2D) decImg.createGraphics();
                        g2.setColor(new Color(160, 160, 160));
                        g2.fillRect(0, 0, thumbWidth, thumbHeight);
                        g2.drawImage(img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH),
                                x, y, null);


                        File decPng = new File(decDir.getPath() + File.separator
                                + String.format("%1$04d", i + 1) + ".png");
                        ImageIO.write(decImg, "png", decPng);

                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            bres = false;
        } finally {

            if (reader != null) {
                reader.dispose();
            }
            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println(("----make Thumbs time----" + (System.currentTimeMillis() - d) + "ms") + "-----make pages---" + numPages);
        return bres;
    }


    /**
     * 旋转tiff文件
     *
     * @param ftiff 要旋转的tiff文件
     * @param angle 旋转角度: 90,180,270
     * @return true表示成功, false表示失败
     */
    static public boolean Rotatetiff(File fTiff, double angle) {
        FileOutputStream out = null;
        File fTiffTmp = new File(fTiff.getPath() + ".tmpABCD.tmp");
//		File ftiffTmp = new File("c:\\io.tif");
        long d = System.currentTimeMillis();
        ImageReader reader = null;
        FileImageInputStream fis = null;

        boolean bres = false;
        try {
            Object[] src = readtiff(fTiff);
            if (src == null) {
                return false;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];
            if (reader != null) {
                int numPages = reader.getNumImages(true);
                if (numPages > 0) {
                    long[] dpiData = gettiffDPI(reader, 0);
                    BufferedImage bi = reader.read(0);
                    RenderedImage dec1 = RotateImg(bi, angle);
                    bres = createtiff(fTiffTmp, new RenderedImage[]{dec1}, dpiData, false);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (reader != null) {
            reader.dispose();
        }
        if (fis != null) {
            try {
                fis.flush();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (bres && fTiffTmp.exists()) {
            fTiff.delete();
            fTiffTmp.renameTo(fTiff);
        }
        System.out.println(("----rotate tiff by IO use time:" + (System.currentTimeMillis() - d) + "ms"));
        return bres;
    }


    /**
     * 在tiff图像上进行盖章操作
     *
     * @param ftiff 单页tiff文件
     * @param stamp 图章tiff文件
     * @param pt    盖章位置
     * @return true表示成功, false表示失败
     */
    static public boolean DrawStamp(File fTiff, File stamp, Point pt) {


        ImageReader reader = null;
        FileImageInputStream fis = null;
        boolean bRes = false;
        try {
            Object[] src = readtiff(fTiff);
            if (src == null) {
                return false;
            }
            reader = (ImageReader) src[0];
            fis = (FileImageInputStream) src[1];
            if (reader != null) {
                int numPages = reader.getNumImages(true);

                if (numPages > 0) {
                    long[] dpiDataSrc = gettiffDPI(reader, 0);

                    BufferedImage imageDec = reader.read(0);

                    long[] dpiData = new long[]{200, 200};
                    BufferedImage img = loadtiff(stamp, dpiData);
                    if (img == null)
                        return false;

                    if (java.lang.Math.abs(dpiData[0] - dpiDataSrc[0]) > 10 ||
                            java.lang.Math.abs(dpiData[1] - dpiDataSrc[1]) > 10) {
                        double factorX = (double) dpiDataSrc[0] / (double) dpiData[0];
                        double factorY = (double) dpiDataSrc[1] / (double) dpiData[1];
                        img = convertRenderedImage(ScaleImg(img, factorX, factorY));
                    }

                    imageDec = DoStamp(imageDec, img, pt);

                    bRes = createtiff(fTiff, new RenderedImage[]{imageDec}, dpiDataSrc, false);

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.dispose();
            }
            if (fis != null) {
                try {
                    fis.flush();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bRes;
    }


    private static BufferedImage convertRenderedImage(RenderedImage img) {

        if (img instanceof BufferedImage) {
            return (BufferedImage) img;
        }

        ColorModel cm = img.getColorModel();

        int width = img.getWidth();
        int height = img.getHeight();
        WritableRaster raster = cm.createCompatibleWritableRaster(width, height);

        boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
        Hashtable<String, Object> properties = new Hashtable<String, Object>();
        String[] keys = img.getPropertyNames();
        if (keys != null) {
            for (int i = 0; i < keys.length; i++) {
                try {
                    properties.put(keys[i], img.getProperty(keys[i]));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        BufferedImage result = new BufferedImage(cm, raster, isAlphaPremultiplied, properties);
        img.copyData(raster);


        return result;
    }

    private static RenderedImage RGBToBilevel(RenderedImage srcImg,
                                              boolean isErrorDiffusion) {
        // Load the ParameterBlock for the dithering operation
        // and set the operation name.
        RenderedImage res = null;
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(srcImg);
        String opName = null;
        if (isErrorDiffusion) {
            opName = "errordiffusion";
            LookupTableJAI lut = new LookupTableJAI(new byte[][]{
                    {(byte) 0x00, (byte) 0xff}, {(byte) 0x00, (byte) 0xff},
                    {(byte) 0x00, (byte) 0xff}});
            pb.add(lut);
            pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
        } else {
            opName = "ordereddither";
            ColorCube cube = ColorCube.createColorCube(DataBuffer.TYPE_BYTE, 0,
                    new int[]{2, 2, 2});
            pb.add(cube);
            pb.add(KernelJAI.DITHER_MASK_443);
        }
        // Create a layout containing an IndexColorModel which maps
        // zero to zero and unity to 255; force SampleModel to be bilevel.
        ImageLayout layout = new ImageLayout();
        byte[] map = new byte[]{(byte) 0x00, (byte) 0xff};
        ColorModel cm = new IndexColorModel(1, 2, map, map, map);
        layout.setColorModel(cm);
        SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
                srcImg.getWidth(), srcImg.getHeight(), 1);
        layout.setSampleModel(sm);
        // Create a hint containing the layout.
        RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
        // Dither the image.
        res = JAI.create(opName, pb, hints);
        return res;

    }

    private static RenderedImage RotateImg(RenderedImage img, double angle) {
        ParameterBlock params = new ParameterBlock();
        params.addSource(img);
        if (angle == 90.0) {
            params.add(TransposeDescriptor.ROTATE_90);
            return JAI.create("Transpose", params, null);
        } else if (angle == 180.0) {
            params.add(TransposeDescriptor.ROTATE_180);
            return JAI.create("Transpose", params, null);
        } else if (angle == 270.0) {
            params.add(TransposeDescriptor.ROTATE_270);
            return JAI.create("Transpose", params, null);
        }
        Interpolation interp = Interpolation
                .getInstance(Interpolation.INTERP_BILINEAR);
        params.add(0.0F);
        params.add(0.0F);
        params.add((float) java.lang.Math.toRadians(angle));
        params.add(interp);
        return JAI.create("rotate", params, null);
    }


    private static RenderedImage ScaleImg(RenderedImage img, double factorX, double factorY) {
        BufferedImage imgB = convertRenderedImage(img);
        int iType = imgB.getType();
        if (iType == BufferedImage.TYPE_BYTE_BINARY || iType == BufferedImage.TYPE_CUSTOM
                || iType == BufferedImage.TYPE_BYTE_INDEXED)
            iType = BufferedImage.TYPE_3BYTE_BGR;
        double newWidth = img.getWidth() * factorX;
        double newHeight = img.getHeight() * factorX;
        System.out.println( img.getWidth());
        System.out.println( img.getHeight());
        BufferedImage bufferedImage = new BufferedImage((int) newWidth, (int) newHeight, iType);
        bufferedImage.getGraphics().drawImage(imgB.getScaledInstance((int) newWidth, (int) newHeight, Image.SCALE_SMOOTH), 0, 0, null);
        return bufferedImage;
    }

    private static RenderedImage DoAndImg(RenderedImage img1, RenderedImage img2) {
        ParameterBlock params = new ParameterBlock();
        params.addSource(img1);
        params.addSource(img2);
        return JAI.create("And", params, null);

    }

    private static RenderedImage DoOrImg(RenderedImage img1, RenderedImage img2) {
        ParameterBlock params = new ParameterBlock();
        params.addSource(img1);
        params.addSource(img2);
        return JAI.create("Or", params, null);

    }


    private static BufferedImage DoStamp(BufferedImage image1,
                                         BufferedImage image2, Point pt) throws Exception {


        int imgTp1 = image1.getType();
        int imgTp2 = image2.getType();
        System.out.println("imgTp1=" + imgTp1 + ", imgTp2=" + imgTp2 +
                ", BufferedImage.TYPE_BYTE_BINARY=" + BufferedImage.TYPE_BYTE_BINARY);
        if (BufferedImage.TYPE_BYTE_BINARY == imgTp1
                && imgTp2 != BufferedImage.TYPE_BYTE_BINARY) {

            BufferedImage tmpImg = new BufferedImage(image1.getWidth(),
                    image1.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
            tmpImg.createGraphics().drawImage(image1, 0, 0, null);
            image1 = tmpImg;
        }
        if (BufferedImage.TYPE_BYTE_BINARY == imgTp2
                && imgTp1 != BufferedImage.TYPE_BYTE_BINARY) {

            BufferedImage tmpImg = new BufferedImage(image2.getWidth(),
                    image2.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
            tmpImg.createGraphics().drawImage(image2, 0, 0, null);
            image2 = tmpImg;
        }

//		BufferedImage TmpImg2 = new BufferedImage(image2.getWidth(),
//				image2.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
//		TmpImg2.createGraphics().drawImage(image1, 0, 0, image2.getWidth(),
//				image2.getHeight(), pt.x, pt.y, pt.x + image2.getWidth(),
//				pt.y + image2.getHeight(), null);
//		RenderedImage res = DoAndImg(TmpImg2, image2);

        Graphics2D g2 = image1.createGraphics();
        g2.drawImage(image2, pt.x, pt.y, null);

        return image1;


    }


    private static boolean createtiff(File fTiff, RenderedImage[] images, long[] dpiData, boolean bFax) {
        // //
        if (dpiData == null || dpiData.length != 2 || fTiff == null || images == null || images.length == 0)
            return false;

        RenderedImage img1 = null;
        FileOutputStream out = null;
        boolean bres = false;
        try {
            int iCompress = TIFFEncodeParam.COMPRESSION_GROUP4;
            for (int i = 0; i < images.length; ++i) {
                if (images[i].getColorModel().getPixelSize() > 1) {
                    if (bFax) {
                        images[i] = RGBToBilevel(images[i], true);
                    } else {
                        iCompress = TIFFEncodeParam.COMPRESSION_PACKBITS;
                        break;
                    }
                }
            }
            img1 = images[0];
            out = new FileOutputStream(fTiff);
            TIFFEncodeParam paramEnc = new tiffEncodeParam();
            paramEnc.setCompression(iCompress);
            ImageEncoder encoder = ImageCodec.createImageEncoder("tiff", out, paramEnc);
            Vector<RenderedImage> lastImgs = new Vector<RenderedImage>();
            if (images.length > 1) {
                for (int i = 1; i < images.length; ++i)
                    lastImgs.add(images[i]);
                paramEnc.setExtraImages(lastImgs.iterator());
            }
            if (dpiData[0] > 0 || dpiData[1] > 0) {
                int fieldCount = 1;
                if (dpiData[0] > 0 && dpiData[1] > 0) {
                    fieldCount = 2;
                }
                fieldCount += 1;
                TIFFField[] tiffFields = new tiffField[fieldCount];
                int index = 0;
                if (dpiData[0] > 0) {
                    long xdpiArray[][] = new long[1][2];
                    xdpiArray[0] = new long[]{dpiData[0], 1};
                    TIFFField xRes = new tiffField(
                            TIFFImageDecoder.TIFF_X_RESOLUTION,
                            TIFFField.TIFF_RATIONAL, 1, xdpiArray);
                    tiffFields[index++] = xRes;
                }
                if (dpiData[1] > 0) {
                    long ydpiArray[][] = new long[1][2];
                    ydpiArray[0] = new long[]{dpiData[1], 1};
                    TIFFField yRes = new tiffField(
                            TIFFImageDecoder.TIFF_Y_RESOLUTION,
                            TIFFField.TIFF_RATIONAL, 1, ydpiArray);
                    tiffFields[index++] = yRes;
                }
                TIFFField fSoft = new tiffField(0x0131, TIFFField.TIFF_ASCII,
                        1, new String[]{"bena create"});
                tiffFields[index++] = fSoft;
                paramEnc.setExtraFields(tiffFields);
            }
            encoder.encode(img1);
            bres = true;
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return bres;
    }
}

 

下面是pom.xml中的依赖

<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.15</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.maven/maven-repository-metadata -->
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-repository-metadata</artifactId>
            <version>3.6.3</version>
        </dependency>
<!--从github上面找到有关于tiff文件操作的依赖包-->
        <dependency>
            <groupId>com.github.jai-imageio</groupId>
            <artifactId>jai-imageio-core</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!--  https://mvnrepository.com/artifact/javax.media/jai-core-->
        <dependency>
        <groupId>javax.media</groupId>
        <artifactId>jai-core</artifactId>
        <version>1.1.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.sun.media/jai-codec -->
        <dependency>
            <groupId>com.sun.media</groupId>
            <artifactId>jai-codec</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.adobe.xmp/xmpcore -->
        <dependency>
            <groupId>com.adobe.xmp</groupId>
            <artifactId>xmpcore</artifactId>
            <version>5.1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.drewnoakes/metadata-extractor -->
        <dependency>
            <groupId>com.drewnoakes</groupId>
            <artifactId>metadata-extractor</artifactId>
            <version>2.14.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!--读取tiff的依赖包-->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-tiff</artifactId>
            <version>3.3.2</version>
        </dependency>
posted @ 2021-01-23 19:22  lelea  阅读(2354)  评论(0编辑  收藏  举报