`
asdzheng
  • 浏览: 96017 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Image读取CMYK和Tif 报错的解决办法

阅读更多
   上一篇说到,Image.read()返回空是null,引入一个包就行。后来要讲读取到的图片缩小,还是会报错。没办法只得先把它先转换成其他格式的图片才能进行缩小,处理办法,为先判断图片的真实格式,用下面类里的getRealFormatName(),如果为Tif格式,先将它转成其他可被ImageIO读取的格式covertTif就可以了。
   后来又碰到一种情况,就是读取的图片有些不是RGB颜色,而是CMYK设置的颜色,此时会报不支持此格式的错误。内容如下:
   javax.imageio.IIOException: Unsupported Image Type 
   at com.sun.imageio.plugins.jpeg.JPEGImageReader.readInternal(Unknown Source) 
   at com.sun.imageio.plugins.jpeg.JPEGImageReader.read(Unknown Source)
   ....
   同样需要将图片的颜色转为RGB再作读取,这里的处理方法是,不用系统自带的ImageIO读取图片,而用下面这个类的readImage(file)方法,这个方法里会对CMYK颜色的图片做特殊处理。
   
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import javax.imageio.IIOException;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.sanselan.ImageReadException;
import org.apache.sanselan.Sanselan;
import org.apache.sanselan.common.byteSources.ByteSource;
import org.apache.sanselan.common.byteSources.ByteSourceFile;
import org.apache.sanselan.formats.jpeg.JpegImageParser;
import org.apache.sanselan.formats.jpeg.segments.UnknownSegment;

public class ImageTool {

    private static boolean hasAdobeMarker = false;
    private static Log log = LogFactory.getLog(ImageTool.class);
	
	/*
	 *返回图片的真实格式,此方法如果读取的图片为svg格式会返回空值
	 */
    public static String getRealFormatName(Object object) throws Exception {
        ImageInputStream iis = ImageIO.createImageInputStream(object);
        Iterator<ImageReader> iterator = ImageIO.getImageReaders(iis);
        while (iterator.hasNext()) {
            ImageReader reader = (ImageReader) iterator.next();
            return reader.getFormatName();
        }
        return null;
    }
	
	/*
	 *传图片的路径,和要将图片转成的格式
	 */
    public static void convertTif(String fileName, String extension) {
        try {
            File file = new File(fileName);
            if (file.exists() == false) {
                System.out.println("File not exist!!!");
                return;
            }
            BufferedImage image = ImageIO.read(file);
            BufferedImage convertedImage = new BufferedImage(image.getWidth(),
                    image.getHeight(), BufferedImage.TYPE_INT_RGB);
            convertedImage.createGraphics().drawRenderedImage(image, null);
            ImageIO.write(convertedImage, extension, new File(fileName));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

	/*
	 *传进需要读取的图片,fileName是用来记录CMYK图片的名字
	 */
    public static BufferedImage readImage(File file, String fileName) throws      IOException, ImageReadException {
        hasAdobeMarker = false;
        ImageInputStream stream = ImageIO.createImageInputStream(file);
        Iterator<ImageReader> iter = ImageIO.getImageReaders(stream);
        while (iter.hasNext()) {
            ImageReader reader = iter.next();
            reader.setInput(stream);

            BufferedImage image;
            ICC_Profile profile = null;
            try {
                image = reader.read(0);
            } catch (IIOException e) {
                checkAdobeMarker(file);
                profile = Sanselan.getICCProfile(file);
                WritableRaster raster = (WritableRaster) reader.readRaster(0, null);
                if (hasAdobeMarker) {
                    convertInvertedColors(raster);`
                }
                image = convertCmykToRgb(raster, profile);
                log.info("The CMYK FileName ========" + fileName);
            }
            return image;
        }
        return null;
    }

    private static void checkAdobeMarker(File file) throws IOException, ImageReadException {
        JpegImageParser parser = new JpegImageParser();
        ByteSource byteSource = new ByteSourceFile(file);
        @SuppressWarnings("rawtypes")
        ArrayList segments = parser.readSegments(byteSource, new int[]{0xffee}, true);
        if (segments != null && segments.size() >= 1) {
            UnknownSegment app14Segment = (UnknownSegment) segments.get(0);
            byte[] data = app14Segment.bytes;
            if (data.length >= 12 && data[0] == 'A' && data[1] == 'd' && data[2] == 'o' && data[3] == 'b' && data[4] == 'e') {
                hasAdobeMarker = true;
            }
        }
    }

    private static void convertInvertedColors(WritableRaster raster) {
        int height = raster.getHeight();
        int width = raster.getWidth();
        int stride = width * 4;
        int[] pixelRow = new int[stride];
        for (int h = 0; h < height; h++) {
            raster.getPixels(0, h, width, 1, pixelRow);
            for (int x = 0; x < stride; x++) {
                pixelRow[x] = 255 - pixelRow[x];
            }
            raster.setPixels(0, h, width, 1, pixelRow);
        }
    }

    private static BufferedImage convertCmykToRgb(Raster cmykRaster, ICC_Profile cmykProfile) throws IOException {
        if (cmykProfile == null) //读取CMYK的色彩配置文件
        {
            cmykProfile = ICC_Profile.getInstance(ImageTool.class.getResourceAsStream("ISOcoated_v2_300_eci.icc"));
        }
        ICC_ColorSpace cmykCS = new ICC_ColorSpace(cmykProfile);
        BufferedImage rgbImage = new BufferedImage(cmykRaster.getWidth(), cmykRaster.getHeight(), BufferedImage.TYPE_INT_RGB);
        WritableRaster rgbRaster = rgbImage.getRaster();
        ColorSpace rgbCS = rgbImage.getColorModel().getColorSpace();
        ColorConvertOp cmykToRgb = new ColorConvertOp(cmykCS, rgbCS, null);
        cmykToRgb.filter(cmykRaster, rgbRaster);
        return rgbImage;
    }
}
    


    此类需要引入一个包和ISOcoated_v2_300_eci.icc(CMYK的位图);
   
    注:CMYK转RGB参考自stackoverflow :
http://stackoverflow.com/questions/3123574/how-to-convert-from-cmyk-to-rgb-in-java-correctly?lq=1 codo君的答案;
分享到:
评论
1 楼 yangzg216 2014-01-11  
你好,我用你的方法试了一下,色差太严重了。不知道还有没有更好一点的方法。

相关推荐

    读取Tiff文件中CMYK色彩模式存储的图像数据,并转换为RGB色彩模式

    读取CMYK色彩模式的Tiff文件,通常需要借助图像处理库,如Python的Pillow库或者Java的ImageIO。这些库提供了API来解析Tiff文件的元数据,包括色彩模式信息,并能访问每个像素的CMYK值。例如,在Python中,可以使用...

    C#读取tif格式图片

    本篇文章将深入探讨如何使用C#来处理和读取TIFF(Tagged Image File Format)格式的图片,这是一种常见的多页图像文件格式,常用于扫描仪和传真机。在C#中实现这一功能,我们需要借助于.NET Framework或.NET Core...

    读取单通道的tif格式图片

    对于图像处理和分析任务,特别是涉及单通道图像的情况,正确地读取和处理TIFF文件是非常重要的。本文将详细介绍如何使用OpenCV库读取单通道的TIFF格式图片,并提供一个简单的示例程序来展示这一过程。 #### OpenCV...

    已编译好可直接使用VS解析TIFF\TIF格式文件所需库

    TIFF(Tagged Image File Format)和TIF是同一种图像文件格式,广泛用于专业图像处理、扫描仪和印刷行业,因为它们支持多种颜色模式、压缩算法和多页文档。在Visual Studio(VS)中解析TIFF或TIF文件,通常需要依赖...

    tif.rar_tif_文件格式

    TIFF(Tagged Image File Format)文件格式是一种广泛用于存储图像和图形的文件格式,尤其在专业摄影、扫描和印刷领域。它具有高度的灵活性,支持多种色彩模式(如灰度、RGB、CMYK)、压缩算法(无损和有损)、以及...

    TIFF文件读取

    这个库允许开发者读取、写入、修改TIFF文件,包括支持多种压缩算法(如无压缩、LZW、JPEG等)和色彩空间(灰度、RGB、CMYK等)。 ### 使用TiffLib读取TIFF文件 1. **初始化库**:首先,需要包含`tiflib.h`头文件,...

    VC读取tiff格式影像文件

    在图像处理领域,TIFF(Tagged Image File Format)是一种常见的图像文件格式,它支持多种图像类型,包括灰度、彩色、位图等,并且可以存储多页图像,因此常用于扫描仪和图像编辑软件。在Windows编程环境中,Visual ...

    tif文件查看器

    这种格式能够存储大量的图像数据,并且支持多种色彩模式,如灰度、RGB和CMYK,以及多种压缩算法,包括无损和有损压缩。"tif文件查看器"是指专门用来打开和查看TIFF文件的软件工具。 TIFF文件的特性包括: 1. **多层...

    cmyk.zip_CMYK_放射

    在描述中提到的“读入tif文件”,TIFF(Tagged Image File Format)是一种常见的图像文件格式,支持多种色彩模式,包括CMYK,常用于专业图像处理和打印。在航空摄影图像处理中,TIFF文件可以存储高分辨率的图像数据...

    Bmp2Tif example

    在IT行业中,图像处理是一项非常重要的技术,而Bmp2Tif这个例子就涉及到了两种常见的图像格式:BMP(Bitmap)和TIFF(Tagged Image File Format)。这两种格式各有其特点,适用于不同的应用场景。 首先,BMP是...

    TifI图像读取及四则运算

    TIF是一种灵活的位图格式,支持多种压缩算法和图像类型,包括灰度、RGB彩色、CMYK等。它允许存储元数据,如分辨率、颜色空间信息等,这使得TifImage类的设计需要考虑到这些特性,以便正确地解析和保存图像信息。 `...

    pic&tif图像转换与图像挖取程序.rar_PIC_open_tif_图像 tif

    标题中的“pic&tif图像转换与图像挖取程序.rar”表明这是一个关于图像处理的软件或代码包,专注于pic和tif两种图像格式之间的转换,并具备从图像中挖取特定区域的功能。描述进一步解释了该程序的核心功能,即图像...

    读取大于 4GB 的 TIF 图像:一些 TIF 写入器写入大于 4GB 的图像文件-matlab开发

    本文将深入探讨如何在MATLAB中读取和处理这些大文件,以及解决4GB以上TIFF图像的读取问题。 TIFF是一种灵活的位图图像格式,允许存储单层或多层图像,包括灰度、RGB彩色、CMYK颜色模式等。由于其广泛的支持和可扩展...

    Tif文件合并工具

    TIFF(Tagged Image File Format)是一种常见的图像文件格式,尤其在扫描仪和专业图形领域广泛应用。它支持多种颜色模式,如灰度、RGB、CMYK等,并且可以存储多页图像,使得TIFF成为合并多页文档的理想选择。在处理...

    TIFF 图像文件读写源代码

    TIFF(Tagged Image File Format)是一种灵活的位图图像格式,广泛用于扫描仪和光绘设备,以及在图形、图像软件中。它的主要特点是可以存储多种类型的数据,包括灰度图像、彩色图像以及不同深度的像素数据。由于其可...

    多帧tif转pdf.zip

    在IT行业中,图像处理是重要的一环,而TIF(Tagged Image File Format)是一种广泛使用的高质量图像格式,尤其在专业摄影、扫描和印刷领域。多帧TIFF文件,也称为多页TIFF,通常用于存储一系列连续的图像,比如动画...

    商业编程-源码-TIF格式图像文件初探.zip

    本资料“商业编程-源码-TIF格式图像文件初探.zip”提供了深入理解TIF格式图像文件的源代码,帮助开发者掌握如何在自己的项目中读取、操作和保存这种格式的图像。 TIF是一种灵活的位图图像格式,它支持多种图像模式...

    opencv基本读写显示图像.rar_opencv geotif_opencv tif_opencv/图像读写_tif open

    在标题和描述中提到的是关于OpenCV在处理TIFF(Tagged Image File Format)和GeoTIFF图像方面的操作,包括读取、写入以及可视化显示。下面将详细解释这些知识点。 1. **OpenCV 2.4.9**: 这是OpenCV的一个特定版本,...

    读取tiff格式图片并显示

    TIFF(Tagged Image File Format)是一种常见的图像文件格式,广泛用于专业摄影、扫描和图形设计领域。这种格式支持多种图像类型,包括灰度、彩色、位图等,并且允许包含多页、多层和丰富的元数据。在处理TIFF文件时...

Global site tag (gtag.js) - Google Analytics